|
|
@ -48,22 +48,27 @@ |
|
|
|
<!--耗材页面 --> |
|
|
|
<div class="main-top"> |
|
|
|
<div class="plate-area"> |
|
|
|
<SpttingPlates :plates="plates" :temperature="currentTemperature" /> |
|
|
|
<SpttingPlates |
|
|
|
:plates="consumableStore.consumableData?.reactionPlateGroup" |
|
|
|
:temperature="currentTemperature" |
|
|
|
@updateReactionPlateNum="updateReactionPlateNum" |
|
|
|
@unloadConsumable="handleUnloadConsumable" |
|
|
|
/> |
|
|
|
|
|
|
|
<!-- <SliderAreaEx v-model="sliderValue" v-model:totalValue="totalVal"/> |
|
|
|
<DragAreaEx v-model:hVal="hVal" v-model:hTotal="hTotal" v-model:vVal="vVal" v-model:vTotal="vTotal"/> --> |
|
|
|
</div> |
|
|
|
<div class="move-liquid-area"> |
|
|
|
<MoveLiquidArea |
|
|
|
:isLoad="isLoadedConsumables" |
|
|
|
:isLoading="isLoading" |
|
|
|
:moveLiquids="moveLiquids" |
|
|
|
:tempTipNum="tempTipNum" |
|
|
|
:bufferBig="bufferBig" |
|
|
|
:moveLiquids="consumableStore.consumableData?.tips" |
|
|
|
:tempTipNum=" |
|
|
|
consumableStore.consumableData?.tips.map((t) => t.tipNum) |
|
|
|
" |
|
|
|
:bufferBig="consumableStore.consumableData.larBottleGroup" |
|
|
|
:emergencyInfo="emergencyInfo" |
|
|
|
:wasteStatus="wasteStatus" |
|
|
|
@loadConsumables="handleIsLoad" |
|
|
|
@unloadConsumables="handleIsUnload" |
|
|
|
@unloadConsumables="handleUnloadAll" |
|
|
|
@updateTipNum="updateTipNum" |
|
|
|
/> |
|
|
|
</div> |
|
|
@ -76,10 +81,10 @@ |
|
|
|
</div> |
|
|
|
<div class="ball-area"> |
|
|
|
<MainComponent |
|
|
|
v-for="(item, idx) in bufferLittles" |
|
|
|
v-for="(item, idx) in consumableStore.consumableData?.littBottleGroup" |
|
|
|
:key="idx" |
|
|
|
class="ball-grid" |
|
|
|
:projectName="item.projShortName" |
|
|
|
:projectName="item.projShortName || ''" |
|
|
|
:currentCount="item.num" |
|
|
|
:totalBalls="25" |
|
|
|
:activatedBalls="item.num" |
|
|
@ -91,6 +96,18 @@ |
|
|
|
/> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<InitWarn |
|
|
|
v-if="showUnloadConsumableWarnModal" |
|
|
|
:visible="showUnloadConsumableWarnModal" |
|
|
|
title="注意" |
|
|
|
message="请先卸载部分耗材后再扫描耗材" |
|
|
|
cancelText="返回" |
|
|
|
icon="/src/assets/update-pin-icon.svg" |
|
|
|
confirmText="确认" |
|
|
|
@close="confirmWarn" |
|
|
|
@confirm="confirmWarn" |
|
|
|
/> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
|
|
|
@ -104,20 +121,23 @@ import { |
|
|
|
getInitState, |
|
|
|
scanConsumables, |
|
|
|
updateTipsNum, |
|
|
|
updateConsumables, |
|
|
|
unloadAllConsumable, |
|
|
|
unloadConsumable, |
|
|
|
ConsumableGroupNo, |
|
|
|
} from '../../../services/Index/index' |
|
|
|
import { useConsumablesStore, useEmergencyStore } from '../../../store' |
|
|
|
import { useDeviceStore } from '../../../store/index' |
|
|
|
import { ConsumeType, eventBus } from '../../../eventBus' |
|
|
|
import { ReactionPlate, BottleGroup, LiquidState } from '../../../types/Index' |
|
|
|
import { eventBus } from '../../../eventBus' |
|
|
|
import { createWebSocket } from '../../../websocket/socket' |
|
|
|
import type { |
|
|
|
ConsumablesStateMessage, |
|
|
|
SensorStateMessage, |
|
|
|
EmergencyPosStateMessage, |
|
|
|
} from '../../../websocket/socket' |
|
|
|
import InitWarn from '../Components/Consumables/Warn/InitWarn.vue' |
|
|
|
import { getServerInfo } from '../../../utils/getServerInfo' |
|
|
|
import { formatScanReports } from '../../../utils/errorHandler' |
|
|
|
import { devOptions } from '@/constant' |
|
|
|
import { ElMessage } from 'element-plus' |
|
|
|
|
|
|
|
const { wsUrl } = getServerInfo('/api/v1/app/ws/state') |
|
|
@ -130,29 +150,15 @@ const deviceStore = useDeviceStore() |
|
|
|
const currentTemperature = ref(40) |
|
|
|
// 废料区状态 |
|
|
|
const wasteStatus = ref(false) |
|
|
|
// 是否已经加载(扫描)过耗材,界面上展示着耗材 |
|
|
|
const isLoadedConsumables = ref(false) |
|
|
|
// 是否处理加载(扫描)耗材过程中 |
|
|
|
|
|
|
|
// 扫描耗材中 |
|
|
|
const isLoading = ref(false) |
|
|
|
// 反应板夹的状态 |
|
|
|
const plates = ref<ReactionPlate[]>([]) |
|
|
|
// 移液盘的状态 |
|
|
|
const moveLiquids = ref<LiquidState[]>([ |
|
|
|
{ |
|
|
|
id: 1, |
|
|
|
tipNum: 0, |
|
|
|
}, |
|
|
|
{ |
|
|
|
id: 2, |
|
|
|
tipNum: 0, |
|
|
|
}, |
|
|
|
{ |
|
|
|
id: 3, |
|
|
|
tipNum: 0, |
|
|
|
}, |
|
|
|
]) |
|
|
|
|
|
|
|
// 是否显示扫描报告(列表弹窗) |
|
|
|
const showScanResults = ref(false) |
|
|
|
|
|
|
|
const showUnloadConsumableWarnModal = ref(false) |
|
|
|
|
|
|
|
interface ScanReport { |
|
|
|
channel: number |
|
|
|
code: string |
|
|
@ -163,79 +169,20 @@ interface ScanReport { |
|
|
|
} |
|
|
|
const formattedReports = ref<ScanReport[]>([]) |
|
|
|
|
|
|
|
// 临时状态管理小球激活数量 |
|
|
|
const tempTipNum = ref<number[]>([ |
|
|
|
...moveLiquids.value.map((liquid) => liquid.tipNum), |
|
|
|
]) |
|
|
|
//管理缓冲液小的状态 |
|
|
|
interface BufferLittle { |
|
|
|
id: number |
|
|
|
num: number |
|
|
|
projShortName: string |
|
|
|
color: string |
|
|
|
lotId?: string |
|
|
|
type?: string |
|
|
|
projId?: number |
|
|
|
projName?: string |
|
|
|
isInstall?: boolean |
|
|
|
} |
|
|
|
const bufferLittles = ref<BufferLittle[]>([ |
|
|
|
{ |
|
|
|
id: 1, |
|
|
|
num: 0, |
|
|
|
projShortName: '', |
|
|
|
color: '#4caf50', |
|
|
|
}, |
|
|
|
{ |
|
|
|
id: 2, |
|
|
|
num: 0, |
|
|
|
projShortName: '', |
|
|
|
color: '#4caf50', |
|
|
|
}, |
|
|
|
{ |
|
|
|
id: 3, |
|
|
|
num: 0, |
|
|
|
projShortName: '', |
|
|
|
color: '#4caf50', |
|
|
|
}, |
|
|
|
{ |
|
|
|
id: 4, |
|
|
|
num: 0, |
|
|
|
projShortName: '', |
|
|
|
color: '#4caf50', |
|
|
|
}, |
|
|
|
{ |
|
|
|
id: 5, |
|
|
|
num: 0, |
|
|
|
projShortName: '', |
|
|
|
color: '#4caf50', |
|
|
|
}, |
|
|
|
{ |
|
|
|
id: 6, |
|
|
|
num: 0, |
|
|
|
projShortName: '', |
|
|
|
color: '#4caf50', |
|
|
|
}, |
|
|
|
]) |
|
|
|
//管理大缓冲液的状态 |
|
|
|
const bufferBig = ref<BottleGroup[]>( |
|
|
|
Array.from({ length: 6 }, () => ({}) as BottleGroup), |
|
|
|
) |
|
|
|
//急诊区状态 |
|
|
|
const emergencyInfo = ref(emergencyStore.$state.emergencyInfo || {}) |
|
|
|
//提示扫描报告后,是否进一步显示 耗材结果 |
|
|
|
const isHandleScan = ref(false) |
|
|
|
|
|
|
|
// 确认扫描结果 |
|
|
|
const handleConfirmScan = () => { |
|
|
|
showScanResults.value = false |
|
|
|
if (formattedReports.value.some((report) => report.isError)) { |
|
|
|
isHandleScan.value = false |
|
|
|
isLoadedConsumables.value = false |
|
|
|
ElMessage.warning('存在错误,请检查耗材') |
|
|
|
} else { |
|
|
|
isHandleScan.value = true |
|
|
|
} |
|
|
|
} |
|
|
|
const confirmWarn = () => { |
|
|
|
showUnloadConsumableWarnModal.value = false |
|
|
|
} |
|
|
|
|
|
|
|
//使用websocket保证数据的实时性 |
|
|
|
const startWebSocket = () => { |
|
|
|
socket.connect() |
|
|
@ -254,45 +201,14 @@ const handleSensorState = (data: SensorStateMessage['data']) => { |
|
|
|
|
|
|
|
//处理耗材状态 |
|
|
|
const handleConsumablesState = (data: ConsumablesStateMessage['data']) => { |
|
|
|
if (isHandleScan.value) { |
|
|
|
if (!isDragging.value) { |
|
|
|
consumableStore.setConsumablesData(data) |
|
|
|
if (!isDragging.value) { |
|
|
|
moveLiquids.value = data.tips |
|
|
|
tempTipNum.value = [...moveLiquids.value.map((liquid) => liquid.tipNum)] |
|
|
|
plates.value = data.reactionPlateGroup as ReactionPlate[] |
|
|
|
bufferLittles.value = data.littBottleGroup as BufferLittle[] |
|
|
|
bufferBig.value = data.larBottleGroup as BottleGroup[] |
|
|
|
} else { |
|
|
|
console.log('正在拖动,不更新耗材') |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// 使用事件总线更新 反应板和缓冲液状态 |
|
|
|
const updatePlatesAndBuffers = ({ |
|
|
|
type, |
|
|
|
value, |
|
|
|
index, |
|
|
|
}: { |
|
|
|
type: ConsumeType |
|
|
|
value: number |
|
|
|
index: number |
|
|
|
}) => { |
|
|
|
if (type === 'Plate' && plates.value && plates.value[index]) { |
|
|
|
plates.value[index].num = value |
|
|
|
} |
|
|
|
if ( |
|
|
|
type === 'LittleBuf' && |
|
|
|
bufferLittles.value && |
|
|
|
bufferLittles.value[index] |
|
|
|
) { |
|
|
|
bufferLittles.value[index].num = value |
|
|
|
} |
|
|
|
if (type === 'BigBuf' && bufferBig.value && bufferBig.value[index]) { |
|
|
|
bufferBig.value[index].isInstall = value > 0 |
|
|
|
} else { |
|
|
|
console.log('正在拖动,不更新耗材') |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
onMounted(() => { |
|
|
|
eventBus.on('confirm', updatePlatesAndBuffers) |
|
|
|
startWebSocket() |
|
|
|
socket.subscribe<SensorStateMessage>('SensorState', handleSensorState) |
|
|
|
socket.subscribe<ConsumablesStateMessage>( |
|
|
@ -301,8 +217,6 @@ onMounted(() => { |
|
|
|
) |
|
|
|
}) |
|
|
|
onBeforeUnmount(() => { |
|
|
|
// 清除事件总线的监听 |
|
|
|
eventBus.off('confirm', updatePlatesAndBuffers) |
|
|
|
if (socket !== null) { |
|
|
|
socket.disconnect() // 断开连接 |
|
|
|
} |
|
|
@ -315,14 +229,11 @@ onBeforeUnmount(() => { |
|
|
|
// 在组件激活时恢复状态 |
|
|
|
onActivated(() => { |
|
|
|
emergencyInfo.value = emergencyStore.$state.emergencyInfo || {} |
|
|
|
if (!isLoadedConsumables.value) { |
|
|
|
console.log('组件被激活了') |
|
|
|
} |
|
|
|
// if (!isLoadedConsumables.value) { |
|
|
|
// console.log('组件被激活了') |
|
|
|
// } |
|
|
|
}) |
|
|
|
// 子组件传值 |
|
|
|
//存储耗材数据 |
|
|
|
const consumablesData = ref<ConsumablesStateMessage['data'] | null>(null) |
|
|
|
// 修改加载耗材的处理函数 |
|
|
|
|
|
|
|
const handleIsLoad = async () => { |
|
|
|
const res = await getInitState() |
|
|
|
if (res.ecode === 'SUC' && !res.data.deviceInited) { |
|
|
@ -330,99 +241,82 @@ const handleIsLoad = async () => { |
|
|
|
return |
|
|
|
} |
|
|
|
try { |
|
|
|
if ( |
|
|
|
consumableStore.consumableData.reactionPlateGroup.every( |
|
|
|
(p) => !!p.isInstall, |
|
|
|
) |
|
|
|
) { |
|
|
|
showUnloadConsumableWarnModal.value = true |
|
|
|
return |
|
|
|
} |
|
|
|
isLoading.value = true |
|
|
|
const res = await scanConsumables() |
|
|
|
isLoading.value = false |
|
|
|
|
|
|
|
// 格式化扫描结果 |
|
|
|
formattedReports.value = formatScanReports(res.data.scanReports) |
|
|
|
console.log('🚀 ~ handleIsLoad ~ formattedReports:', formattedReports.value) |
|
|
|
// 显示扫描结果弹窗 |
|
|
|
showScanResults.value = true |
|
|
|
consumablesData.value = res.data.consumableState |
|
|
|
if (res.success) { |
|
|
|
// 格式化扫描结果 |
|
|
|
formattedReports.value = formatScanReports(res.data.scanReports) |
|
|
|
console.log( |
|
|
|
'🚀 ~ handleIsLoad ~ formattedReports:', |
|
|
|
formattedReports.value, |
|
|
|
) |
|
|
|
// 显示扫描结果弹窗 |
|
|
|
showScanResults.value = true |
|
|
|
} else { |
|
|
|
ElMessage.error(res.data.info) |
|
|
|
} |
|
|
|
} catch (error) { |
|
|
|
console.error('加载耗材失败:', error) |
|
|
|
isLoading.value = false |
|
|
|
isHandleScan.value = false |
|
|
|
ElMessage.error('加载耗材失败') |
|
|
|
} |
|
|
|
} |
|
|
|
watch(isHandleScan, (newVal) => { |
|
|
|
if (newVal) { |
|
|
|
// 确认后更新状态 |
|
|
|
if (consumablesData.value) { |
|
|
|
moveLiquids.value = consumablesData.value.tips |
|
|
|
plates.value = consumablesData.value.reactionPlateGroup as ReactionPlate[] |
|
|
|
bufferLittles.value = consumablesData.value |
|
|
|
.littBottleGroup as BufferLittle[] |
|
|
|
bufferBig.value = consumablesData.value.larBottleGroup as BottleGroup[] |
|
|
|
tempTipNum.value = [...moveLiquids.value.map((liquid) => liquid.tipNum)] |
|
|
|
isLoadedConsumables.value = true |
|
|
|
consumableStore.setConsumablesData(consumablesData.value) |
|
|
|
} |
|
|
|
} else { |
|
|
|
// 取消时清空临时数据 |
|
|
|
consumablesData.value = null |
|
|
|
|
|
|
|
const handleUnloadAll = async () => { |
|
|
|
const res = await unloadAllConsumable() |
|
|
|
if (res.success) { |
|
|
|
// 接口未返回数据 |
|
|
|
} |
|
|
|
} |
|
|
|
const handleUnloadConsumable = async (index: number) => { |
|
|
|
const res = await unloadConsumable({ |
|
|
|
group: `CG${index + 1}` as ConsumableGroupNo, |
|
|
|
}) |
|
|
|
if (!res.success && res.data.info) { |
|
|
|
ElMessage.error(res.data.info) |
|
|
|
} |
|
|
|
}) |
|
|
|
const handleIsUnload = () => { |
|
|
|
isLoadedConsumables.value = !isLoadedConsumables.value |
|
|
|
isLoading.value = false |
|
|
|
isHandleScan.value = false |
|
|
|
// 重置 moveLiquids 和 tempTipNum |
|
|
|
moveLiquids.value = [ |
|
|
|
{ id: 1, tipNum: 0 }, |
|
|
|
{ id: 2, tipNum: 0 }, |
|
|
|
{ id: 3, tipNum: 0 }, |
|
|
|
] |
|
|
|
tempTipNum.value = [...moveLiquids.value.map((liquid) => liquid.tipNum)] |
|
|
|
plates.value = [] |
|
|
|
emergencyStore.unloadInfo() |
|
|
|
emergencyInfo.value = {} as EmergencyPosStateMessage['data']['tube'] |
|
|
|
console.log('emergencyInfo===', emergencyInfo) |
|
|
|
bufferLittles.value = [ |
|
|
|
{ |
|
|
|
id: 1, |
|
|
|
num: 0, |
|
|
|
projShortName: '', |
|
|
|
color: '#4caf50', |
|
|
|
}, |
|
|
|
{ |
|
|
|
id: 2, |
|
|
|
num: 0, |
|
|
|
projShortName: '', |
|
|
|
color: '#4caf50', |
|
|
|
}, |
|
|
|
{ |
|
|
|
id: 3, |
|
|
|
num: 0, |
|
|
|
projShortName: '', |
|
|
|
color: '#4caf50', |
|
|
|
}, |
|
|
|
{ |
|
|
|
id: 4, |
|
|
|
num: 0, |
|
|
|
projShortName: '', |
|
|
|
color: '#4caf50', |
|
|
|
}, |
|
|
|
{ |
|
|
|
id: 5, |
|
|
|
num: 0, |
|
|
|
projShortName: '', |
|
|
|
color: '#4caf50', |
|
|
|
}, |
|
|
|
{ |
|
|
|
id: 6, |
|
|
|
num: 0, |
|
|
|
projShortName: '', |
|
|
|
color: '#4caf50', |
|
|
|
}, |
|
|
|
] |
|
|
|
bufferBig.value = Array.from({ length: 6 }, () => ({ num: 0, isInstall: false })) |
|
|
|
} |
|
|
|
|
|
|
|
const isDragging = ref(false) |
|
|
|
|
|
|
|
const updateReactionPlateNum = async ({ |
|
|
|
index, |
|
|
|
plateNum, |
|
|
|
sync, |
|
|
|
}: { |
|
|
|
index: number |
|
|
|
plateNum: number |
|
|
|
sync: boolean |
|
|
|
}) => { |
|
|
|
if (plateNum < 0) { |
|
|
|
return |
|
|
|
} |
|
|
|
if (deviceStore.status === 'IDLE') { |
|
|
|
consumableStore.updateReactionPlateNum(index, plateNum) |
|
|
|
if (sync) { |
|
|
|
console.log(`🚀 ~ updatePlateNum ~ order ${index + 1}, num ${plateNum}`) |
|
|
|
try { |
|
|
|
await updateConsumables({ group: `CG${index + 1}`, num: plateNum }) |
|
|
|
} catch (error) { |
|
|
|
console.error('修改耗材数量失败:', error) |
|
|
|
} |
|
|
|
isDragging.value = false |
|
|
|
} else { |
|
|
|
isDragging.value = true |
|
|
|
} |
|
|
|
} else { |
|
|
|
ElMessage.error('设备正在工作,无法修改数值') |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const updateTipNum = async ({ |
|
|
|
index, |
|
|
|
tipNum, |
|
|
@ -432,18 +326,19 @@ const updateTipNum = async ({ |
|
|
|
tipNum: number |
|
|
|
sync: boolean |
|
|
|
}) => { |
|
|
|
if (tipNum < 0) { return } |
|
|
|
if (tipNum < 0) { |
|
|
|
return |
|
|
|
} |
|
|
|
if (deviceStore.status === 'IDLE') { |
|
|
|
tempTipNum.value[index] = tipNum |
|
|
|
//调用接口 |
|
|
|
consumableStore.updateTipNum(index, tipNum) |
|
|
|
if (sync) { |
|
|
|
console.log(`🚀 ~ updateTipNum ~ order ${index + 1}, num ${tipNum}`) |
|
|
|
isDragging.value = false |
|
|
|
try { |
|
|
|
await updateTipsNum({ group: `TipG${index + 1}`, num: tipNum }) |
|
|
|
} catch (error) { |
|
|
|
console.error('修改耗材数量失败:', error) |
|
|
|
} |
|
|
|
isDragging.value = false |
|
|
|
} else { |
|
|
|
isDragging.value = true |
|
|
|
} |
|
|
|