Browse Source

梳理运行功能

dev
LiLongLong 7 months ago
parent
commit
eb60d40701
  1. 267
      src/pages/Index/Regular/Running.vue

267
src/pages/Index/Regular/Running.vue

@ -11,7 +11,8 @@
<span>{{ <span>{{
getBloodTypeLabel(selectedItem.bloodType) || '无类型' getBloodTypeLabel(selectedItem.bloodType) || '无类型'
}}</span> }}</span>
<span>{{ getRemainingTime(selectedItem) }}</span>
<!--使用store中tank中的remain字段-->
<span>{{ 1234545634 }}</span>
</template> </template>
<template v-else> </template> <template v-else> </template>
</div> </div>
@ -109,7 +110,8 @@
item.projInfo.projShortName || '无项目' item.projInfo.projShortName || '无项目'
}}</span> }}</span>
<span class="barcode">{{ item.sampleBarcode || '无条码' }}</span> <span class="barcode">{{ item.sampleBarcode || '无条码' }}</span>
<span class="time">{{ getRemainingTime(item) }}</span>
<!--todo-->
<span class="time">{{ 1234 }}</span>
</template> </template>
<div <div
:style="`margin-top:140px;background-color:${currentIndex == index ? 'red' : 'rgb(149, 149, 149)'}`" :style="`margin-top:140px;background-color:${currentIndex == index ? 'red' : 'rgb(149, 149, 149)'}`"
@ -125,7 +127,7 @@
<div <div
class="emergency-button" class="emergency-button"
:class="{ disabled: hasEmergencyPosition }" :class="{ disabled: hasEmergencyPosition }"
@click="!hasEmergencyPosition && (showEmergencyAlert = !showEmergencyAlert)"
@click="confirmEmergency()"
> >
<span>急诊</span> <span>急诊</span>
</div> </div>
@ -202,33 +204,6 @@
</div> </div>
</teleport> </teleport>
<!-- 急诊弹窗提示 --> <!-- 急诊弹窗提示 -->
<teleport to="body">
<div v-if="showEmergencyAlert" class="alert-overlay">
<div class="alert-container">
<div class="alert-icon">
<img class="icon" src="@/assets/emergency.svg" />
<span></span>
</div>
<div class="alert-message">确认要添加急诊吗</div>
<div class="action-buttons">
<el-button type="info" @click="cancelEmergency" class="confirm-button"
>取消</el-button
>
<el-button
type="primary"
@click="confirmEmergency"
class="cancel-button"
>确认</el-button
>
</div>
</div>
</div>
</teleport>
<EmergencyResultDialog
:result="emergencyResult!"
:visible="isDialogVisible"
@update:visible="confirmEmergencyWarn"
/>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@ -236,7 +211,6 @@ import {
ref, ref,
onMounted, onMounted,
onUnmounted, onUnmounted,
watch,
onActivated, onActivated,
computed, computed,
} from 'vue' } from 'vue'
@ -246,29 +220,20 @@ import { getBloodTypeLabel } from '../utils'
import { import {
PlateDisplay, PlateDisplay,
LittleBufferDisplay, LittleBufferDisplay,
EmergencyResultDialog,
} from '../components' } from '../components'
import tubeItem from '../components/TestTube/Tube.vue' import tubeItem from '../components/TestTube/Tube.vue'
import BallGrid from '../components/Consumables/BallGrid.vue' import BallGrid from '../components/Consumables/BallGrid.vue'
import { getRunningList } from '@/services/Index/running/running' import { getRunningList } from '@/services/Index/running/running'
import type { import type {
EmergencyPosStateMessage,
ProjectInfo,
SubTank, SubTank,
} from '@/websocket/socket' } from '@/websocket/socket'
import { useEmergencyStore } from '@/store/modules/emergency'
import { useRunningStore } from '@/store/modules/running' import { useRunningStore } from '@/store/modules/running'
const emergencyStore = useEmergencyStore()
const consumablesStore = useConsumablesStore() const consumablesStore = useConsumablesStore()
const runningStore = useRunningStore() const runningStore = useRunningStore()
const deviceStore = useDeviceStore() const deviceStore = useDeviceStore()
const settingTubeStore = useSettingTestTubeStore() const settingTubeStore = useSettingTestTubeStore()
const router = useRouter() const router = useRouter()
const route = useRoute()
// //
const sampleTube = { const sampleTube = {
userid: 'user123', userid: 'user123',
@ -281,77 +246,17 @@ const hasEmergencyPosition = ref(false)
onMounted(() => { onMounted(() => {
// //
// //
fetchIncubationData()
}) })
//
watch(
() => emergencyStore.emergencyInfo,
(newData) => {
if (newData) {
const emergencyInfo = newData as EmergencyPosStateMessage['data']['tube']
if (emergencyInfo.projInfo && Array.isArray(emergencyInfo.projInfo)) {
emergencyInfo.projInfo.forEach(
(project: ProjectInfo, index: number) => {
//@ts-ignore
const subtank: SubTank = {
pos: `EMERGENCY-${index + 1}`,
state: 'INCUBATING',
bloodType: emergencyInfo.bloodType,
sampleBarcode: emergencyInfo.sampleBarcode,
userid: emergencyInfo.userid,
projInfo: project,
sampleId: `${emergencyInfo.sampleId}-${index}`,
projId: project.projId,
startIncubatedTime: Date.now(),
incubatedTimeSec: 300,
errors: [],
isEmergency: true,
}
//
// incubationPlates.value.push(SubTank)
},
)
}
fetchEmergencyData()
}
},
)
// //
onActivated(() => { onActivated(() => {
fetchEmergencyData()
}) })
//
const showEmergencyAlert = ref(false)
// //
const confirmEmergency = () => { const confirmEmergency = () => {
showEmergencyAlert.value = false
router.push('/index/emergency') router.push('/index/emergency')
} }
//
const confirmEmergencyWarn = (val: any) => {
console.log('急诊结果:', val)
isDialogVisible.value = false
}
//
const fetchEmergencyData = () => {
const emergencyQuery = route.query.emergencyData as string
if (emergencyQuery) {
emergencyData.value = JSON.parse(emergencyQuery)
console.log('急诊数据:', emergencyData.value)
}
}
//
const cancelEmergency = () => {
showEmergencyAlert.value = false
}
// //
let selectedPlateStyle = computed(()=>{ let selectedPlateStyle = computed(()=>{
let borderColor = selectedItem.value ? 'blue' : '#ffffff' let borderColor = selectedItem.value ? 'blue' : '#ffffff'
@ -366,11 +271,9 @@ let selectedPlateStyle = computed(()=>{
// const selectedSamples = ref<number[]>([]) // const selectedSamples = ref<number[]>([])
// //
// //
const incubationPlates = ref<SubTank[]>([])
const selectedItem = ref<SubTank | null>(null) // const selectedItem = ref<SubTank | null>(null) //
const selectedItemId = ref<string | null>(null) // const selectedItemId = ref<string | null>(null) //
const TOTAL_SLOTS = 20 // const TOTAL_SLOTS = 20 //
const emergencyData = ref<SubTank | null>(null)
// //
const getRotationStyle = (item: SubTank, index: number) => { const getRotationStyle = (item: SubTank, index: number) => {
@ -378,6 +281,7 @@ const getRotationStyle = (item: SubTank, index: number) => {
const angleStep = 360 / totalItems const angleStep = 360 / totalItems
const angle = index * angleStep const angle = index * angleStep
//todo
return { return {
transform: ` transform: `
translate(-50%, -50%) /* 将矩形中心点移到圆心 */ translate(-50%, -50%) /* 将矩形中心点移到圆心 */
@ -389,9 +293,7 @@ const getRotationStyle = (item: SubTank, index: number) => {
? '#f0f0f0' ? '#f0f0f0'
: selectedItemId.value === item.sampleId : selectedItemId.value === item.sampleId
? '#1890ff' ? '#1890ff'
: getRemainingTime(item) === '已完成'
? '#ff4d4f'
: 'transparent',
: 'transparent',
borderWidth: '3px', borderWidth: '3px',
borderStyle: 'solid', borderStyle: 'solid',
} }
@ -406,8 +308,8 @@ const getItemStyle = (item: SubTank, index) => {
backgroundColor: '#f8f8f8', // backgroundColor: '#f8f8f8', //
} }
} }
const remainingTime = getRemainingTime(item)
//todo
let remainingTime = '1';//
return { return {
backgroundColor: item.projInfo.color,//item.isEmergency ? '#ffeded' : item.projInfo.color, // backgroundColor: item.projInfo.color,//item.isEmergency ? '#ffeded' : item.projInfo.color, //
borderColor: currentIndex.value === index ? 'blue' : remainingTime === '已完成' ? 'red' : 'transparent', borderColor: currentIndex.value === index ? 'blue' : remainingTime === '已完成' ? 'red' : 'transparent',
@ -440,171 +342,22 @@ const getFillStyle = (item: any) => {
// //
//@ts-ignore //@ts-ignore
const isFull = ref(consumablesStore.wasteStatus)
const showWasteAlert = ref(false) const showWasteAlert = ref(false)
// //
const getWasteStyle = () => ({ const getWasteStyle = () => ({
backgroundColor: isFull.value ? '#d9534f' : '#5cb85c', // 绿
backgroundColor: deviceStore.sensorState?.wasteBinFullFlag ? '#d9534f' : '#5cb85c', // 绿
transition: 'background-color 0.3s ease', // transition: 'background-color 0.3s ease', //
}) })
const closeAlert = () => { const closeAlert = () => {
showWasteAlert.value = false showWasteAlert.value = false
if (wasteAlertTimeout) clearTimeout(wasteAlertTimeout) //
}
let wasteAlertTimeout: ReturnType<typeof setTimeout> | null = null
//
const fetchIncubationData = async () => {
try {
const response = await getRunningList()
let data: SubTank[] = []
if (response && response.success) {
// console.log(':', response.data)
//
data = response.data.subtanks.map((plate: SubTank) => ({
...plate,
isSelected: plate.sampleId === selectedItemId.value,
}))
}
//
const filledData = emergencyData.value
? [...data, emergencyData.value]
: data
// 20
while (filledData.length < TOTAL_SLOTS) {
filledData.push({
pos: `PLACEHOLDER-${filledData.length + 1}`,
state: 'EMPTY',
bloodType: "WHOLE_BLOOD",
sampleBarcode: '',
userid: '',
projInfo: {
projId: 0,
projName: '',
projShortName: '',
color: '',
},
startIncubatedTime: 0,
incubatedTimeSec: 0,
remainTimeSec: 0,
sampleId: `PLACEHOLDER-${filledData.length + 1}`,
projId: 0,
errors: [],
isEmergency: false
// isPlaceholder: true, //
})
}
// `incubationPlates`
// incubationPlates.value = filledData
//
updateStartTimes()
} catch (error) {
console.error('获取孵育盘列表失败:', error)
// 使
const filledData = emergencyData.value ? [emergencyData.value] : []
while (filledData.length < TOTAL_SLOTS) {
filledData.push({
pos: `PLACEHOLDER-${filledData.length + 1}`,
state: 'EMPTY',
bloodType: 'WHOLE_BLOOD',
sampleBarcode: '',
userid: '',
projInfo: {
projId: 0,
projName: '',
projShortName: '',
color: '',
},
startIncubatedTime: 0,
incubatedTimeSec: 0,
remainTimeSec: 0,
sampleId: `PLACEHOLDER-${filledData.length + 1}`,
projId: 0,
errors: [],
isEmergency: false,
// isPlaceholder: true,
})
}
// incubationPlates.value = filledData
}
}
//
const startTimes = ref<Record<string, number>>({})
const updateStartTimes = () => {
const currentTime = Date.now() //
incubationPlates.value?.forEach((plate) => {
if (!startTimes.value[plate.pos]) {
startTimes.value[plate.pos] = currentTime //
}
})
}
//
const getRemainingTime = (plate: SubTank) => {
if(!plate.projId){
return;
}
const startTime = startTimes.value[plate.pos] || Date.now()
const elapsed = (Date.now() - startTime) / 1000 //
const remaining = Math.max(0, plate.incubatedTimeSec - elapsed) // 0
if (remaining === 0) return '已完成'
const minutes = Math.floor(remaining / 60)
const seconds = Math.floor(remaining % 60)
return `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`
}
const emergencyResult = ref() //
const isDialogVisible = ref(false) //
let emergencyCompleted = ref(false) //
//
const watchEmergencyCompletion = () => {
watch(
() => incubationPlates.value,
(newPlates) => {
const emergencyPlate = newPlates.find(
(plate) => plate.isEmergency,
)
if (emergencyPlate && getRemainingTime(emergencyPlate) === '已完成') {
if (!emergencyCompleted.value) {
//
emergencyResult.value = {
date: new Date().toLocaleString(),
sampleBarcode: emergencyPlate.sampleBarcode,
projInfo: emergencyPlate.projInfo,
bloodType: emergencyPlate.bloodType,
operator: 'admin', //
expiryDate: '2025-12-31', //
serialNumber: 'SN12345678', //
reference: '参考值', //
value: '5.24 mg/L', //
}
isDialogVisible.value = true
emergencyCompleted.value = true //
}
}
},
{ deep: true },
)
} }
onMounted(() => { onMounted(() => {
watchEmergencyCompletion()
}) })
// //
onUnmounted(() => { onUnmounted(() => {
isDialogVisible.value = false
emergencyResult.value = null
}) })
</script> </script>

Loading…
Cancel
Save