Browse Source

试管架页面改为监听上报

dev
zhangjiming 7 months ago
parent
commit
a04d50e55a
  1. 63
      src/pages/Index/Index.vue
  2. 155
      src/pages/Index/Regular/TestTube.vue
  3. 3
      src/store/modules/consumables.ts
  4. 11
      src/store/modules/testTube.ts
  5. 16
      src/types/Index/TestTube.ts
  6. 21
      src/websocket/socket.ts

63
src/pages/Index/Index.vue

@ -238,6 +238,7 @@ import {
useConsumablesStore,
useDeviceStore,
useSettingTestTubeStore,
useTestTubeStore,
} from '../../store'
import { createWebSocket } from '../../websocket/socket'
import type {
@ -247,6 +248,7 @@ import type {
IncubationPlateStateMessage,
OptScanModuleStateMessage,
SensorStateMessage,
TubeHolderSettingMessage,
TubeHolderStateMessage,
} from '../../websocket/socket'
import { getServerInfo } from '../../utils/getServerInfo'
@ -269,6 +271,7 @@ const consumableStore = useConsumablesStore()
const deviceStore = useDeviceStore()
const runningStore = useRunningStore()
const settingTubeStore = useSettingTestTubeStore()
const tubeRackStore = useTestTubeStore()
//
const user = ref<User>(
@ -367,6 +370,9 @@ const handleFooterState = (data: FooterMessageState['data']) => {
const handleTubeHolderStateMessage = (data: TubeHolderStateMessage['data']) => {
runningStore.setTubeHolderState(data)
}
const handleTubeHolderSettingMessage = (data: TubeHolderSettingMessage['data']) => {
tubeRackStore.setTubeRacks(data)
}
const handleOptScanModuleStateMessage = (
data: OptScanModuleStateMessage['data'],
@ -406,6 +412,7 @@ onMounted(() => {
'TubeHolderState',
handleTubeHolderStateMessage,
)
wsState.subscribe<TubeHolderSettingMessage>('TubeHolderSetting', handleTubeHolderSettingMessage)
wsState.subscribe<IncubationPlateStateMessage>(
'IncubationPlateState',
handleIncubationPlateStateMessage,
@ -454,10 +461,10 @@ const startTest = async () => {
try {
showDeviceWaitingModal.value = true
const res = await startWork()
showDeviceWaitingModal.value = false
if (res.success) {
await untilDeviceReady()
} else {
showDeviceWaitingModal.value = false
ElMessage({
message: res.data.info,
type: 'error',
@ -473,10 +480,10 @@ const startTest = async () => {
const pauseTest = async () => {
showDeviceWaitingModal.value = true
const res = await pauseWork()
showDeviceWaitingModal.value = false
if (res.success) {
await untilDeviceReady()
} else {
showDeviceWaitingModal.value = false
ElMessage({
message: res.data.info,
type: 'error',
@ -489,10 +496,10 @@ const pauseTest = async () => {
const stopTest = async () => {
showDeviceWaitingModal.value = true
const res = await stopWork()
showDeviceWaitingModal.value = false
if (res.success) {
await untilDeviceReady()
} else {
showDeviceWaitingModal.value = false
ElMessage({
message: res.data.info,
type: 'error',
@ -504,10 +511,10 @@ const stopTest = async () => {
const continueTest = async () => {
showDeviceWaitingModal.value = true
const res = await continueWork()
showDeviceWaitingModal.value = false
if (res.success) {
await untilDeviceReady()
} else {
showDeviceWaitingModal.value = false
ElMessage({
message: res.data.info,
type: 'error',
@ -546,55 +553,11 @@ const pollingInitState = async () => {
showFailModal.value = true //
}
}
} else {
showDeviceResettingModal.value = false
}
}
// const checkIfResetCompleted = async () => {
// if (showFailModal.value) {
// showFailModal.value = false;
// }
// showLoadingModal.value = true; // LoadingModal
// // 2
// await new Promise(resolve => setTimeout(resolve, 2000));
// //
// const initState = await getInitState();
// if (initState.ecode === "SUC") {
// //
// if (initState.data.passed) {
// console.log("")
// sessionStorage.setItem('deviceResetFinished', "true");
// showLoadingModal.value = false;
// showAlreadyModal.value = true;
// } else {
// console.log("")
// await getCheckData(); //
// const failedItems = checkData.value.filter(item => !item.pass);
// if (failedItems.length > 0) {
// const errorMessages = generateErrorMessages(failedItems);
// console.log(':', errorMessages);
// failItems.value = failedItems; //
// failMessage.value = errorMessages.join('\n'); //
// showLoadingModal.value = false; // LoadingModal
// showFailModal.value = true; //
// } else {
// console.log("")
// showLoadingModal.value = false; // LoadingModal
// showAlreadyModal.value = true; //
// sessionStorage.setItem('deviceResetFinished', "true");
// }
// }
// }
// };
// const isTestTubeSlotReady = ref(false); //
//
// const checkTestTubeSlotStatus = (data: CheckItem[]) => {
// const slotCheck = data.find(item => item.type === 'CHECK_TEST_TUBE_SLOT_READY');
// isTestTubeSlotReady.value = slotCheck?.pass ?? false;
// console.log(':', isTestTubeSlotReady.value ? '' : '');
// };
const handleAlreadyConfirm = () => {
console.log('用户确认操作')
showAlreadyModal.value = false

155
src/pages/Index/Regular/TestTube.vue

@ -3,15 +3,15 @@
<!-- 渲染试管架列表 -->
<div class="tube-rack-list">
<div
v-for="(tubeRack, index) in tubeRacks"
v-for="(tubeRack, index) in testTubeStore.tubeRacks"
:key="tubeRack.uuid"
class="tube-rack-container"
>
<TestTubeRack
<TestTubeRackComponent
:tubeRack="tubeRack"
:index="index"
:projects="consumables.projectsAvailable"
:bloodTypes="bloodTypes"
:bloodTypes="settingTubeStore.bloodTypes"
@delete:rack="deleteTubeRack"
@active:rack="handleActivateChange"
@patient:edit="handleChangeUser"
@ -30,7 +30,10 @@
<section class="project-area">
<h2 class="title">项目选择</h2>
<div class="project-list">
<div v-for="proj in consumables.projectsAvailable" :key="proj.projName">
<div
v-for="proj in consumables.projectsAvailable"
:key="proj.projName"
>
<div
class="project-item"
:class="{ active: isProjElemActive(proj) }"
@ -39,7 +42,7 @@
>
<span class="proj-name">{{ proj.projName }}</span>
<span class="proj-num">{{
`${projIdCntMap[proj.projId] || 0}/${proj.num}`
`${projIdCntMap[proj.projId || 1] || 0}/${proj.num}`
}}</span>
</div>
</div>
@ -48,7 +51,7 @@
<section class="blood-type-area">
<h2 class="title">血液类型</h2>
<div class="blood-list">
<div v-for="type in bloodTypes" :key="type.key">
<div v-for="type in settingTubeStore.bloodTypes" :key="type.key">
<div
class="blood-item"
:class="{ active: selectedBloodTypeKey === type.key }"
@ -74,67 +77,44 @@
</div>
</template>
<script setup>
import {
ref,
onMounted,
onBeforeUnmount,
nextTick,
computed,
onActivated,
} from 'vue'
<script setup lang="ts">
import { ref, computed } from 'vue'
import * as R from 'ramda'
import { useRouter } from 'vue-router'
import TestTubeRack from '../components/TestTube/TestTubeRack.vue'
import TestTubeRackComponent from '../components/TestTube/TestTubeRack.vue'
import {
addTestTube,
getTestTube,
deleteTube,
updateTubeConfig,
getBloodTypes,
updateTubeActivationStatus,
} from '../../../services/Index/testTube'
import { eventBus } from '../../../eventBus'
import {
useConsumablesStore,
useTestTubeStore,
useSettingTestTubeStore,
} from '../../../store'
import { ElMessage, ElDialog } from 'element-plus'
import { ReactionPlateGroup, TestTubeRack } from '@/websocket/socket'
const router = useRouter()
const settingTubeStore = useSettingTestTubeStore()
const testTubeStore = useTestTubeStore()
const consumables = useConsumablesStore()
const tubeRacks = ref([]) //<DataItem[]>
const bloodTypes = ref([])
const loading = ref(false) //
const selectedProjIds = ref([]) // number[]
const selectedProjIds = ref<number[]>([])
const selectedBloodTypeKey = ref('WHOLE_BLOOD')
const deleteRackDialogVisible = ref(false)
const onTubeSettingUpdate = () => {
getTubeData()
const isProjElemActive = (proj: ReactionPlateGroup) => {
return selectedProjIds.value.includes(proj.projId!)
}
onMounted(() => {
eventBus.on('AppTubeSettingUpdateEvent', onTubeSettingUpdate)
getTubeData()
getBloodTypeData()
})
onBeforeUnmount(() => {
eventBus.off('AppTubeSettingUpdateEvent', onTubeSettingUpdate)
})
const isProjElemActive = (proj) => {
return selectedProjIds.value.includes(proj.projId)
}
const styleOfProjElem = (proj) => {
const styleOfProjElem = (proj: ReactionPlateGroup) => {
const active = isProjElemActive(proj)
if (active) {
return {
@ -151,13 +131,13 @@ const styleOfProjElem = (proj) => {
}
}
const clickProjectItem = (proj) => {
if (selectedProjIds.value.includes(proj.projId)) {
const clickProjectItem = (proj: ReactionPlateGroup) => {
if (selectedProjIds.value.includes(proj.projId!)) {
selectedProjIds.value = selectedProjIds.value.filter(
(pId) => pId !== proj.projId,
)
} else {
selectedProjIds.value = [...selectedProjIds.value, proj.projId].sort()
selectedProjIds.value = [...selectedProjIds.value, proj.projId!].sort()
}
}
@ -189,55 +169,13 @@ const projIdCntMap = computed(() => {
return acc
},
{},
tubeRacks.value,
testTubeStore.tubeRacks,
)
})
const getBloodTypeData = async () => {
loading.value = true
const res = await getBloodTypes()
loading.value = false
if (res.success) {
bloodTypes.value = res.data
// console.log(res.data)
} else {
ElMessage({
message: '加载血液类型失败',
type: 'error',
duration: 2000,
})
}
}
const mockData = (data) => {
// if (data.length > 0) {
// data[0].tubeSettings.splice(0, 2)
// }
return data
}
//
const getTubeData = async () => {
loading.value = true
const res = await getTestTube()
if (res.success) {
tubeRacks.value = mockData(res.data)
// console.log(tubeRacks.value)
} else {
ElMessage({
message: '加载试管架数据失败',
type: 'error',
duration: 2000,
})
}
loading.value = false
}
//
const handleChangeUser = async (index) => {
const rack = tubeRacks.value[index]
const handleChangeUser = async (index: number) => {
const rack = testTubeStore.tubeRacks[index]
if (rack.state !== 'INACTIVE') {
ElMessage({
message: '试管架处理激活状态,不可修改',
@ -252,25 +190,21 @@ const handleChangeUser = async (index) => {
})
}
const existValidProject = (tubeRack) => {
const existValidProject = (tubeRack: TestTubeRack) => {
return tubeRack.tubeSettings.some(
(s) => (s.projId || []).length > 0 && !!s.bloodType,
)
}
let confirmDeleteRackUuid = null
let confirmDeleteRackUuid: string | undefined = undefined
const confirmDeleteTube = async () => {
deleteRackDialogVisible.value = false
const res = await deleteTube(confirmDeleteRackUuid)
const res = await deleteTube(confirmDeleteRackUuid!)
if (res.success) {
tubeRacks.value = tubeRacks.value.filter(
(v) => v.uuid !== confirmDeleteRackUuid,
)
ElMessage({
message: '删除成功',
type: 'success',
})
// getTubeData()
} else {
ElMessage({
message: '删除失败',
@ -280,8 +214,8 @@ const confirmDeleteTube = async () => {
}
//
const deleteTubeRack = async (idx) => {
const rack = tubeRacks.value[idx]
const deleteTubeRack = async (idx: number) => {
const rack = testTubeStore.tubeRacks[idx]
if (rack.state !== 'INACTIVE') {
ElMessage({
message: '试管架处理激活状态,不可删除',
@ -302,7 +236,7 @@ const addTubeRack = async () => {
const response = await addTestTube()
if (response && response.success) {
tubeRacks.value = [...tubeRacks.value, response.data]
// do nothing
} else {
ElMessage({
message: '试管架添加失败',
@ -313,8 +247,8 @@ const addTubeRack = async () => {
}
//
const handleActivateChange = async (index) => {
const rack = tubeRacks.value[index]
const handleActivateChange = async (index: number) => {
const rack = testTubeStore.tubeRacks[index]
if (rack.state === 'LOCKED') {
ElMessage({
message: '试管已锁定,不能修改',
@ -332,12 +266,7 @@ const handleActivateChange = async (index) => {
active: destState === 'ACTIVE',
})
if (res.success) {
tubeRacks.value = tubeRacks.value.map((rack, idx) => {
if (idx === index) {
rack.state = destState
}
return rack
})
// do nothing
} else {
ElMessage({
message: '更改激活状态失败',
@ -346,12 +275,12 @@ const handleActivateChange = async (index) => {
}
}
const updateTubeSettings = async (rackIdx, tubeIdx) => {
const updateTubeSettings = async (rackIdx:number, tubeIdx:number) => {
if (!selectedBloodTypeKey.value) {
ElMessage.error('请选择血液类型')
return
}
const rack = tubeRacks.value[rackIdx]
const rack = testTubeStore.tubeRacks[rackIdx]
if (rack.state !== 'INACTIVE') {
ElMessage({
message: '试管架已激活,不能修改',
@ -372,17 +301,7 @@ const updateTubeSettings = async (rackIdx, tubeIdx) => {
setting: [updSetting],
})
if (response.success) {
tubeRacks.value = tubeRacks.value.map((rack, idx) => {
if (idx === rackIdx) {
rack.tubeSettings = rack.tubeSettings.map((tube, index) => {
if (index === tubeIdx) {
return updSetting
}
return tube
})
}
return rack
})
// do nothing
} else {
ElMessage.error('设置更新失败')
}

3
src/store/modules/consumables.ts

@ -10,6 +10,7 @@ import * as R from 'ramda'
// import type { PersistenceOptions } from 'pinia-plugin-persistedstate'
import type {
ConsumablesStateMessage,
ProjectInfo,
ReactionPlateGroup,
} from '../../websocket/socket'
@ -79,7 +80,7 @@ export const useConsumablesStore = defineStore(
group[n] as ReactionPlateGroup[],
),
)
return projArr
return projArr as ReactionPlateGroup[]
})
const tipCount = computed(() => {

11
src/store/modules/testTube.ts

@ -1,6 +1,7 @@
import { TestTubeRack, TubeHolderSettingMessage } from '@/websocket/socket'
import { defineStore } from 'pinia'
import { ref } from 'vue'
import type { TestTubeRack } from '../../types/Index'
export const useTestTubeStore = defineStore(
'testTube',
() => {
@ -11,9 +12,17 @@ export const useTestTubeStore = defineStore(
tubeRack.value = rack
}
const tubeRacks = ref<TubeHolderSettingMessage['data']>([])
const setTubeRacks = (data: TubeHolderSettingMessage['data']) => {
tubeRacks.value = data
}
return {
tubeRack,
setTubeRack,
tubeRacks,
setTubeRacks
}
},
{

16
src/types/Index/TestTube.ts

@ -1,12 +1,6 @@
import type { ConsumableGroupBase } from '../../websocket/socket'
import type { ConsumableGroupBase, TestTubeRack } from '../../websocket/socket'
export interface TubeSetting {
tubeIndex: number
userid: string
sampleBarcode: string
projId: number[]
bloodType: 'WHOLE_BLOOD' | 'SERUM_OR_PLASMA'
}
// 更新后的类型定义
export interface Project {
id: number
@ -17,12 +11,6 @@ export interface Project {
reactionTemperature: number
color: string
}
export interface TestTubeRack {
uuid: string
state: 'INACTIVE' | 'ACTIVE' | 'LOCKED'
tubeSettings: TubeSetting[],
tubeInfo:{}
}
export interface ApiResponse {
dataType: string

21
src/websocket/socket.ts

@ -170,6 +170,26 @@ interface TubeHolderStateMessage extends BaseMessage {
timestamp: number
}
export interface TubeSetting {
tubeIndex: number
userid: string
sampleBarcode: string
projId: number[]
bloodType: 'WHOLE_BLOOD' | 'SERUM_OR_PLASMA'
}
export interface TestTubeRack {
uuid: string
state: 'INACTIVE' | 'ACTIVE' | 'LOCKED'
tubeSettings: TubeSetting[],
}
export interface TubeHolderSettingMessage extends BaseMessage {
type: 'TubeHolderSetting'
messageType: 'Report'
dataType: 'TubeHolderSetting'
data: TestTubeRack[]
}
// 传感器状态消息
interface SensorStateMessage extends BaseMessage {
type: 'SensorState'
@ -274,6 +294,7 @@ type WebSocketMessage =
| DeviceWorkStateMessage
| EmergencyPosStateMessage
| TubeHolderStateMessage
| TubeHolderSettingMessage
| SensorStateMessage
| IncubationPlateStateMessage
| AppEventMessage

Loading…
Cancel
Save