forked from gzt/A8000
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
371 lines
10 KiB
371 lines
10 KiB
<template>
|
|
<div id="configuration-container" v-loading="loading">
|
|
<!-- 渲染试管架列表 -->
|
|
<div class="tube-rack-list">
|
|
<div v-for="(tubeRack, index) in tubeRacks" :key="`${tubeRack.uuid || index}-${componentRefreshKey}`"
|
|
class="tube-rack-container">
|
|
<TestTubeRack ref="tubeRackComponentInstance" :tubeRack="tubeRack" :plates="plates" :key="refreshKey"
|
|
@updateActivate="handleActivateChange" @updateSelectedSamples="handleUpdateSelectedSamples"
|
|
@deleteTubeRack="deleteHandle" @changeUser="handleChangeUser"
|
|
@clearProjectSelection="clearProjectSelection" />
|
|
</div>
|
|
</div>
|
|
<!-- 添加试管架按钮 -->
|
|
<div class="add-tube" @click="addTubeRack">
|
|
<div class="icon">
|
|
<img src="@/assets/add.svg" alt="Add Icon" />
|
|
</div>
|
|
<div class="text">添加试管架</div>
|
|
</div>
|
|
<!-- 试管信息编辑 -->
|
|
<ProjectSelector :uuid="UUID" v-model:visible="showProjectSelector" :selectedSampleIds="selectedSampleIdsInParent"
|
|
@updateSample="handleSampleUpdate" @confirm="handleConfirmProjectSelector" @cancel="closeProjectSelector"
|
|
@clearSelection="clearProjectSelection" />
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, onMounted, nextTick } from 'vue'
|
|
import { useRouter } from 'vue-router'
|
|
import TestTubeRack from '../components/TestTube/TestTubeRack.vue'
|
|
import {
|
|
addTestTube,
|
|
getTestTube,
|
|
getProjectInfo,
|
|
deleteTube,
|
|
updateTubeConfig,
|
|
} from '../../../services/Index/Test-tube/test-tube'
|
|
import type {
|
|
DataItem,
|
|
TubeSetting,
|
|
} from '../../../types/Index/index'
|
|
import { ConsumableGroupBase } from '../../../websocket/socket'
|
|
import ProjectSelector from '../components/Consumables/ProjectSelector.vue'
|
|
import { useConsumablesStore, useTestTubeStore, useSettingTestTubeStore } from '../../../store'
|
|
import { ElMessage } from 'element-plus'
|
|
const router = useRouter()
|
|
const testTubeStore = useTestTubeStore()
|
|
const settingTestTubeStore = useSettingTestTubeStore()
|
|
const consumables = useConsumablesStore()
|
|
const tubeRacks = ref<DataItem[]>([])
|
|
const loading = ref(false) // 控制加载状态
|
|
const plates = ref<ConsumableGroupBase[]>(consumables.plates)
|
|
const refreshKey = ref(0)
|
|
const selectedUUID = ref<string>('')
|
|
|
|
// 初始化获取试管架数据
|
|
onMounted(() => {
|
|
getTubeData()
|
|
getProjectInfoData()
|
|
})
|
|
//获取设备支持的项目信息
|
|
const getProjectInfoData = async () => {
|
|
const res = await getProjectInfo()
|
|
if (res.success) {
|
|
console.log(res.data)
|
|
}
|
|
}
|
|
//获取已经配置的试管信息
|
|
const getTubeData = async () => {
|
|
loading.value = true
|
|
const res = await getTestTube()
|
|
if (res.success) {
|
|
// 初始化每个试管架的选中状态
|
|
tubeRacks.value = res.data.map((rack: DataItem) => ({
|
|
...rack,
|
|
selectedSampleIds: [], // 初始化选中状态数组
|
|
}))
|
|
}
|
|
loading.value = false
|
|
}
|
|
const selectedProject = ref<string | null>(null)
|
|
// 添加事件监听,用于清空项目选择状态
|
|
const clearProjectSelection = () => {
|
|
selectedProject.value = null // 清空选中的项目状态
|
|
}
|
|
//编辑患者信息
|
|
const handleChangeUser = async (uuid: string) => {
|
|
selectedUUID.value = uuid
|
|
|
|
const selectedTube = tubeRacks.value.find((t) => t.uuid === selectedUUID.value)
|
|
if (!selectedTube) return
|
|
testTubeStore.setTubeInfo(selectedTube)
|
|
await updateTubeSettingsHandler()
|
|
router.push({
|
|
path: '/index/change-user',
|
|
})
|
|
}
|
|
|
|
//删除试管架
|
|
const deleteHandle = async (uuid: string) => {
|
|
const res = await deleteTube(uuid)
|
|
if (res.success) {
|
|
ElMessage({
|
|
message: '删除成功',
|
|
type: 'success',
|
|
})
|
|
getTubeData()
|
|
} else {
|
|
ElMessage({
|
|
message: '删除失败',
|
|
type: 'error',
|
|
})
|
|
}
|
|
}
|
|
// 添加新试管架
|
|
const addTubeRack = async () => {
|
|
loading.value = true // 开始加载
|
|
const newTubeRack: DataItem = {
|
|
uuid: `uuid-${Date.now()}`,
|
|
active: false,
|
|
lock: false,
|
|
tubeSettings: Array.from({ length: 10 }, (_, index) => ({
|
|
tubeIndex: index,
|
|
userid: '',
|
|
sampleBarcode: '',
|
|
projId: [],
|
|
bloodType: 'WHOLE_BLOOD',
|
|
})),
|
|
selectedSampleIds: [],
|
|
}
|
|
|
|
// 直接将新试管架添加到 tubeRacks 中
|
|
tubeRacks.value.push(newTubeRack)
|
|
// 向服务端发送添加请求
|
|
const response = await addTestTube()
|
|
if (response && response.success) {
|
|
// 更新 tubeRacks 列表为最新数据,避免闪烁
|
|
tubeRacks.value = [...tubeRacks.value]
|
|
} else {
|
|
console.error('试管架添加失败')
|
|
}
|
|
loading.value = false // 加载结束
|
|
}
|
|
|
|
// 处理试管架激活状态变化
|
|
const handleActivateChange = (update: { uuid: string; active: boolean }) => {
|
|
const rack = tubeRacks.value.find((t) => t.uuid === update.uuid)
|
|
if (rack) {
|
|
rack.active = update.active
|
|
}
|
|
}
|
|
const handleSampleUpdate = async ({
|
|
projectIds,
|
|
bloodType,
|
|
}: {
|
|
projectIds: number[]
|
|
bloodType: string
|
|
}): Promise<void> => {
|
|
if (selectedSampleIdsInParent.value.length > 0) {
|
|
// 创建 tubeRacks 的深拷贝
|
|
const updatedTubeRacks = JSON.parse(JSON.stringify(tubeRacks.value))
|
|
// 找到对应的 tubeRack
|
|
const targetTubeRack = updatedTubeRacks.find(
|
|
(t: DataItem) => t.uuid === UUID.value,
|
|
)
|
|
if (targetTubeRack) {
|
|
targetTubeRack.tubeSettings = targetTubeRack.tubeSettings.map(
|
|
(tube: TubeSetting) => {
|
|
if (selectedSampleIdsInParent.value.includes(tube.tubeIndex)) {
|
|
return {
|
|
...tube,
|
|
projId: [...projectIds],
|
|
bloodType: bloodType,
|
|
}
|
|
}
|
|
return tube
|
|
},
|
|
)
|
|
|
|
// 清空数组再重新赋值,确保响应式更新
|
|
tubeRacks.value = []
|
|
await nextTick()
|
|
tubeRacks.value = updatedTubeRacks// 新赋值触发响应式
|
|
console.log("🚀 ~ handleSampleUpdate ~ updatedTubeRacks:", updatedTubeRacks)
|
|
const selectedTube = updatedTubeRacks.find((t: any) => t.uuid === UUID.value)
|
|
console.log("🚀 ~ handleSampleUpdate ~ selectedTube:", selectedTube)
|
|
testTubeStore.setTubeInfo(selectedTube)
|
|
console.log("🚀 ~ handleSampleUpdate ~ testTubeStore.$state.tubeInfo:", testTubeStore.$state.tubeInfo)
|
|
selectedProject.value = null // 选择后清空选中状态
|
|
await nextTick()
|
|
|
|
ElMessage({
|
|
message: '样本信息已更新',
|
|
type: 'success',
|
|
duration: 2000,
|
|
})
|
|
}
|
|
} else {
|
|
ElMessage({
|
|
message: '请先选择样本后再选择项目',
|
|
type: 'warning',
|
|
duration: 2000,
|
|
})
|
|
}
|
|
}
|
|
//声明组件实例
|
|
const UUID = ref<string>('')
|
|
// 当前选中的样本ID列表
|
|
const selectedSampleIdsInParent = ref<number[]>([])
|
|
// 添加一个刷新key
|
|
const componentRefreshKey = ref(0)
|
|
|
|
// 修改 handleConfirmProjectSelector 函数
|
|
const handleConfirmProjectSelector = async () => {
|
|
await updateTubeSettingsHandler()
|
|
|
|
// 清空父组件选中样本列表
|
|
selectedSampleIdsInParent.value = []
|
|
|
|
// 找到当前操作的试管架并清空其选中状态
|
|
const currentTubeRack = tubeRacks.value.find(rack => rack.uuid === UUID.value)
|
|
if (currentTubeRack) {
|
|
currentTubeRack.selectedSampleIds = []
|
|
}
|
|
|
|
// 重置其他相关状态
|
|
showProjectSelector.value = false
|
|
UUID.value = ''
|
|
|
|
ElMessage({
|
|
message: '样本已确认,选中状态已清空',
|
|
type: 'success',
|
|
duration: 2000,
|
|
})
|
|
}
|
|
const tubeRackComponentInstance = ref()
|
|
const showProjectSelector = ref(false)
|
|
|
|
|
|
// 修改关闭项目选择器的方法
|
|
const closeProjectSelector = () => {
|
|
// 找到当前操作的试管架并清空其选中状态
|
|
const currentTubeRack = tubeRacks.value.find(rack => rack.uuid === UUID.value)
|
|
if (currentTubeRack) {
|
|
currentTubeRack.selectedSampleIds = []
|
|
}
|
|
|
|
// 重置所有相关状态
|
|
selectedSampleIdsInParent.value = []
|
|
showProjectSelector.value = false
|
|
UUID.value = ''
|
|
}
|
|
// 父组件代码
|
|
const handleUpdateSelectedSamples = ({ sampleIds, uuid }: { sampleIds: number[]; uuid: string }) => {
|
|
// 更新特定试管架的选中状态
|
|
const tubeRack = tubeRacks.value.find(tube => tube.uuid === uuid)
|
|
if (tubeRack) {
|
|
// 如果是取消选中(sampleIds为空),则关闭弹窗并清空状态
|
|
if (sampleIds.length === 0) {
|
|
showProjectSelector.value = false
|
|
selectedSampleIdsInParent.value = []
|
|
tubeRack.selectedSampleIds = []
|
|
UUID.value = ''
|
|
} else {
|
|
// 如果是新选中,则更新状态并打开弹窗
|
|
tubeRack.selectedSampleIds = sampleIds
|
|
selectedSampleIdsInParent.value = sampleIds
|
|
UUID.value = uuid
|
|
showProjectSelector.value = true
|
|
}
|
|
}
|
|
}
|
|
|
|
// 添加更新试管设置的方法
|
|
const updateTubeSettingsHandler = async () => {
|
|
const { uuid, setting } = settingTestTubeStore.currentConfig
|
|
|
|
if (uuid && setting.tubeIndex >= 0) {
|
|
try {
|
|
const response = await updateTubeConfig({ uuid, setting })
|
|
|
|
if (response.success) {
|
|
ElMessage.success('设置更新成功')
|
|
console.log(tubeRacks.value)
|
|
settingTestTubeStore.clearConfig()
|
|
} else {
|
|
ElMessage.error('设置更新失败')
|
|
}
|
|
} catch (error) {
|
|
console.error('更新试管设置失败:', error)
|
|
ElMessage.error('设置更新失败')
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="less">
|
|
#configuration-container {
|
|
position: relative;
|
|
|
|
.el-message {
|
|
width: 200px;
|
|
height: 200px;
|
|
}
|
|
|
|
/* 主容器定高和滚动条样式 */
|
|
.tube-rack-list {
|
|
max-height: 1200px;
|
|
/* 根据需要设置主容器的最大高度 */
|
|
overflow-y: auto;
|
|
overflow-x: hidden;
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
|
|
/* 自定义滚动条样式 */
|
|
&::-webkit-scrollbar {
|
|
width: 8px;
|
|
}
|
|
|
|
&::-webkit-scrollbar-track {
|
|
background: #f1f1f1;
|
|
}
|
|
|
|
&::-webkit-scrollbar-thumb {
|
|
background: #888;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
&::-webkit-scrollbar-thumb:hover {
|
|
background: #555;
|
|
}
|
|
}
|
|
|
|
.add-tube {
|
|
width: 100%;
|
|
height: 100px;
|
|
background-color: #f6f6f6;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
|
|
.icon {
|
|
width: 60px;
|
|
height: 100px;
|
|
margin-right: 40px;
|
|
}
|
|
|
|
.text {
|
|
font-size: 32px;
|
|
color: #73bc54;
|
|
font-weight: bold;
|
|
}
|
|
}
|
|
|
|
/* 加载状态样式 */
|
|
.loading-overlay {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100vh;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background-color: rgba(255, 255, 255, 0.8);
|
|
font-size: 24px;
|
|
color: #333;
|
|
z-index: 1000;
|
|
}
|
|
}
|
|
</style>
|