Browse Source

重构耗材逻辑

dev
zhangjiming 7 months ago
parent
commit
7a96e7cd5f
  1. 343
      src/pages/Index/Regular/Consumables.vue
  2. 155
      src/pages/Index/components/Consumables/MoveLiquidArea.vue
  3. 30
      src/pages/Index/components/Consumables/SliderAreaEx.vue
  4. 70
      src/pages/Index/components/Consumables/SpttingPlates.vue
  5. 52
      src/services/Index/regular.ts
  6. 79
      src/store/modules/consumables.ts
  7. 22
      src/websocket/socket.ts
  8. 11
      tsconfig.app.json

343
src/pages/Index/Regular/Consumables.vue

@ -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
}

155
src/pages/Index/components/Consumables/MoveLiquidArea.vue

@ -4,18 +4,11 @@
<el-button
type="primary"
class="load-consumables"
v-if="!isLoad"
@click="handleIsLoad"
:loading="isLoading"
@touchstart.prevent="handleTouchStart"
@touchend="handleTouchEnd"
@touchcancel="handleTouchEnd"
>扫描耗材</el-button
>
<el-button
type="danger"
class="load-consumables"
v-if="isLoad"
@click="handleIsUnload"
>卸载耗材</el-button
>
<div class="info-show-area">
<!-- 移液区 -->
<div class="move-liquid-area">
@ -41,7 +34,7 @@
v-if="activeTab === 0"
:order="1"
:total="120"
:activated="moveLiquids![activeTab]?.tipNum"
:activated="moveLiquids[activeTab]?.tipNum"
width="346px"
height="310px"
:columns="12"
@ -93,9 +86,14 @@
@click="showEmergencyInfo(emergencyStore.emergencyInfo)"
>
1
</div>
</div>
</div>
<button class="controller-button" @click="addEmergency" :style="`background-color:${emergencyStatus?'#c84141':'#b4b4b4'}`" :disabled="!emergencyStatus">
<button
class="controller-button"
@click="addEmergency"
:style="`background-color:${emergencyStatus ? '#c84141' : '#b4b4b4'}`"
:disabled="!emergencyStatus"
>
添加急诊
</button>
</div>
@ -138,9 +136,16 @@
</button>
</div>
</div>
<InitWarn v-if="showModal" :visible="showModal" title="提示" message="请及时清理废料箱"
icon="/src/assets/Warn.svg" confirmText="确定" @close="showModal = false"
@confirm="handleConfirm" />
<InitWarn
v-if="showModal"
:visible="showModal"
title="提示"
message="请及时清理废料箱"
icon="/src/assets/Warn.svg"
confirmText="确定"
@close="showModal = false"
@confirm="handleConfirm"
/>
<!--缓冲液大-->
<div class="buffer-area">
<div class="buffer-title">
@ -162,7 +167,6 @@
</div>
</div>
<IdCardInfo v-model="visible"></IdCardInfo>
</template>
<script setup lang="ts">
@ -172,14 +176,18 @@ import IdCardInfo from './IdCardInfo.vue'
import { ref, watch, reactive, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { useEmergencyStore, useConsumablesStore } from '../../../../store'
import { LiquidState, BottleGroup } from '../../../../types/Index/index'
import { LiquidState } from '../../../../types/Index/index'
import wasteFullIcon from '@/assets/Index/waste-full.svg'
import wasteIcon from '@/assets/Index/waste.svg'
import type { EmergencyPosStateMessage } from '@/websocket/socket'
import type {
EmergencyPosStateMessage,
LargeBottleGroup,
} from '@/websocket/socket'
import { createWebSocket } from '@/websocket/socket'
import { isTubeExist } from '@/services/Index/index';
import { InitWarn } from './Warn';
import { isTubeExist } from '@/services/Index/index'
import { InitWarn } from './Warn'
import { getServerInfo } from '@/utils/getServerInfo'
const { wsUrl } = getServerInfo('/api/v1/app/ws/state')
const socket = createWebSocket(wsUrl)
@ -191,13 +199,11 @@ const openTableModal = () => {
}
//
const props = defineProps({
isLoad: Boolean,
isLoading: Boolean,
moveLiquids: {
type: Array as () => Array<LiquidState>,
},
bufferBig: {
type: Array as () => BottleGroup[],
type: Array as () => LargeBottleGroup[],
},
emergencyInfo: {
type: Object as () => EmergencyPosStateMessage['data']['tube'],
@ -206,15 +212,38 @@ const props = defineProps({
wasteStatus: Boolean,
})
const emit = defineEmits([
'loadConsumables',
'unloadConsumables',
'updateTipNum',
])
let longPressTimer: ReturnType<typeof setTimeout> | null = null
const handleTouchStart = () => {
longPressTimer = setTimeout(() => {
longPressTimer = null
emit('unloadConsumables')
}, 1200)
}
const handleTouchEnd = () => {
if (longPressTimer) {
emit('loadConsumables')
clearTimeout(longPressTimer)
longPressTimer = null
}
}
let showModal = ref(false)
const handleConfirm = ()=> {
showModal.value = false;
const handleConfirm = () => {
showModal.value = false
}
//
const wasteStatus = ref(props.wasteStatus)
watch(() => props.wasteStatus, (newVal)=>{
watch(
() => props.wasteStatus,
(newVal) => {
wasteStatus.value = newVal
if(newVal)showModal.value = true;
if (newVal) showModal.value = true
},
{ immediate: true, deep: true },
)
@ -222,73 +251,64 @@ watch(() => props.wasteStatus, (newVal)=>{
const startWebSocket = () => {
socket.connect()
}
const emergencyStateList = ["EMPTY", "TO_BE_PROCESSED", "PROCESS_COMPLETE", "ERROR"];//EMPTY,PROCESS_COMPLETE,ERROR
const emergencyStateList = [
'EMPTY',
'TO_BE_PROCESSED',
'PROCESS_COMPLETE',
'ERROR',
] //EMPTY,PROCESS_COMPLETE,ERROR
onMounted(() => {
//
getEmergencyStatus()
startWebSocket()
socket.subscribe<EmergencyPosStateMessage>('EmergencyPosState', handleEmergencyPosState)
socket.subscribe<EmergencyPosStateMessage>(
'EmergencyPosState',
handleEmergencyPosState,
)
})
let emergencyStatus = ref(false)
//
const handleEmergencyPosState = (data: EmergencyPosStateMessage['data']) => {
// data.tube.state = 'PROCESSING'
let {state} = data.tube;
let { state } = data.tube
// EMPTYTO_BE_PROCESSEDPROCESS_COMPLETEERROR
if(emergencyStateList.includes(state)){
emergencyStatus.value = true;
}else{
emergencyStatus.value = false;
if (emergencyStateList.includes(state)) {
emergencyStatus.value = true
} else {
emergencyStatus.value = false
}
emergencyStore.setInfo(data.tube)
//"PROCESS_COMPLETE",
if(state === 'PROCESS_COMPLETE'){
socket.unsubscribe<EmergencyPosStateMessage>('EmergencyPosState', unSubEmergencyPosState)
if (state === 'PROCESS_COMPLETE') {
socket.unsubscribe<EmergencyPosStateMessage>(
'EmergencyPosState',
unSubEmergencyPosState,
)
}
}
//
const unSubEmergencyPosState = ()=> {
}
const unSubEmergencyPosState = () => {}
//
const getEmergencyStatus = () => {
isTubeExist().then(res => {
isTubeExist().then((res) => {
console.log('这是急诊位状态=1=', res)
if(res && res.data){
if (res && res.data) {
const data = res.data
const { tube } = data;
if(tube && tube.state && emergencyStateList.includes(tube.state)){
emergencyStatus.value = true;
const { tube } = data
if (tube && tube.state && emergencyStateList.includes(tube.state)) {
emergencyStatus.value = true
}
}
})
}
const emit = defineEmits([
'loadConsumables',
'unloadConsumables',
'updateTipNum',
])
//
const handleIsLoad = () => {
emit('loadConsumables')
}
//
const handleIsUnload = () => {
emit('unloadConsumables')
}
//
const activeTab = ref(0)
//
const isActive = ref(false)
watch(
() => props.emergencyInfo,
@ -341,13 +361,16 @@ watch(
{ immediate: true, deep: true },
)
// remainingCount
const handleUpdateTipNum = (remainingCount: number, order: number, sync: boolean) => {
const handleUpdateTipNum = (
remainingCount: number,
order: number,
sync: boolean,
) => {
emit('updateTipNum', { index: order - 1, tipNum: remainingCount, sync })
}
//
const changePlate = (index: number) => {
console.log('切换到', index)
activeTab.value = index
}
</script>

30
src/pages/Index/components/Consumables/SliderAreaEx.vue

@ -47,7 +47,13 @@ const startX = ref(0)
const startValue = ref(0)
const sliderTrack = useTemplateRef('sliderTrack')
const emit = defineEmits(['update:sliderValue', 'update:sliderEndValue'])
const emit = defineEmits([
'update:sliderValue',
'update:sliderEndValue',
'longPress',
])
let longPressTimer = null
watch(
() => props.currValue,
@ -67,6 +73,13 @@ function handleStart(event) {
// console.log(sliderValue.value, totalVal.value)
// console.log(startValue.value, rect.width)
isDragging.value = true
longPressTimer = setTimeout(() => {
if (Math.round(sliderValue.value) === props.currValue) {
emit('longPress', props.order)
}
}, 1200)
document.addEventListener('mousemove', handleDrag)
document.addEventListener('touchmove', handleDrag, { passive: false })
document.addEventListener('mouseup', handleEnd)
@ -74,7 +87,12 @@ function handleStart(event) {
}
function handleDrag(event) {
if (!isDragging.value) return
if (longPressTimer) {
clearTimeout(longPressTimer)
longPressTimer = null
}
if (!sliderTrack.value) return
const touchEvent = event.touches ? event.touches[0] : event
const deltaX = touchEvent.clientX - startX.value
@ -88,8 +106,13 @@ function handleDrag(event) {
}
function handleEnd() {
emit('update:sliderEndValue', sliderValue.value.toFixed(), props.order)
isDragging.value = false
if (longPressTimer) {
clearTimeout(longPressTimer)
longPressTimer = null
} else {
emit('update:sliderEndValue', sliderValue.value.toFixed(), props.order)
}
document.removeEventListener('mousemove', handleDrag)
document.removeEventListener('touchmove', handleDrag)
document.removeEventListener('mouseup', handleEnd)
@ -126,5 +149,4 @@ function handleEnd() {
color: #fff;
-webkit-text-stroke: 2px #000;
}
</style>

70
src/pages/Index/components/Consumables/SpttingPlates.vue

@ -17,8 +17,10 @@
<div class="plate-area">
<div class="plate-bottom" v-if="plates.length > 0">
<span></span>
<span class="project-name">{{ platesValue[i - 1]?.projShortName }}</span>
<span class="project-number">{{ platesValue[i - 1]?.num }}/25</span>
<span class="project-name">{{ plates[i - 1]?.projShortName }}</span>
<span class="project-number">{{
!!plates[i - 1]?.isInstall ? `${plates[i - 1]?.num}/25` : ''
}}</span>
</div>
<div class="plate-bottom" v-else>
<span></span>
@ -27,19 +29,23 @@
</div>
<!-- plates 数组长度不为 0 渲染 Plate 组件否则显示默认的图片 -->
<div v-if="plates.length > 0" class="plate">
<div
v-if="plates.length > 0 && plates[i - 1].isInstall"
class="plate"
>
<Plate
:value="parseInt(platesValue[i - 1].num)"
:color="platesValue[i - 1].color"
:value="parseInt(plates[i - 1].num)"
:color="plates[i - 1].color"
/>
<SliderAreaEx
v-if="platesValue[i - 1].num > 0"
v-if="plates[i - 1].num > 0"
class="slider-area"
:currValue="parseInt(platesValue[i - 1].num)"
:currValue="parseInt(plates[i - 1].num)"
:totalValue="totalVal"
:order="i"
@update:sliderValue="updateSliderVal"
@update:sliderEndValue="updateSliderEndVal"
@longPress="onPlateLongPress"
/>
</div>
<div v-else class="close-circle">
@ -77,52 +83,20 @@ const props = defineProps({
default: 40,
},
})
const emits = defineEmits(['updateReactionPlateNum','unloadConsumable'])
const platesValue = ref(props.plates)
const totalVal = ref(25)
const isDragging = ref(false)
const deviceStore = useDeviceStore()
watch(
() => props.plates,
(newValue) => {
if (!isDragging.value) {
platesValue.value = newValue
}
},
)
const updateSliderVal = async (plate, order) => {
if (deviceStore.status === 'IDLE' && plate >= 0) {
isDragging.value = true
// eventBus.emit('confirm', {
// type: 'Plate',
// value: plate,
// index: order - 1,
// })
platesValue.value[order - 1].num = plate
} else {
ElMessage.error('设备正在工作,无法修改数值')
}
const onPlateLongPress = (order) => {
emits('unloadConsumable', order - 1)
}
const updateSliderEndVal = async (plate, order) => {
isDragging.value = false
if (deviceStore.status === 'IDLE' && plate >= 0) {
try {
const res = await updateConsumables({ group: `CG${order}`, num: plate })
if (res.success) {
// eventBus.emit('confirm', {
// type: 'Plate',
// value: plate,
// index: order - 1,
// })
}
} catch (error) {
console.error('更新失败:', error)
}
} else {
ElMessage.error('设备正在工作,无法修改数值')
}
const updateSliderVal = async (plateNum, order) => {
emits('updateReactionPlateNum', { index: order - 1, plateNum, sync: false })
}
const updateSliderEndVal = async (plateNum, order) => {
emits('updateReactionPlateNum', { index: order - 1, plateNum, sync: true })
}
// const changeNumRef = ref()

52
src/services/Index/regular.ts

@ -1,17 +1,4 @@
import apiClient from '../../utils/axios'
//点击耗材页面加载耗材按钮
export const loadConsumables = async () => {
try {
const res = await apiClient.get('/api/regular/consumables')
return res.data
} catch (error) {
console.log(error)
}
}
type oneConsumableParams = {
group: number
num: number
}
//耗材扫描接口
export const scanConsumables = async () => {
@ -26,21 +13,44 @@ export const scanConsumables = async () => {
}
}
//耗材扫描单组
export const oneScanConsumable = async (data: oneConsumableParams) => {
export const unloadAllConsumable = async () => {
try {
const res = await apiClient.post(
'/api/v1/app/consumableScan/oneScanConsumable',
{
...data,
},
'/api/v1/app/consumablesMgr/unInstallAllConsumable',
)
console.log('单组扫描返回结果:', res)
return res.data
} catch (error) {
console.log('单组扫描出错:', error)
console.log(error)
}
}
export type ConsumableGroupNo = 'CG1' | 'CG2' | 'CG3' | 'CG4' | 'CG5' | 'CG6'
export const unloadConsumable = async (params: {
group: ConsumableGroupNo
}) => {
const res = await apiClient.post(
'/api/v1/app/consumablesMgr/unInstallConsumable',
null,
{ params },
)
return res.data
}
//耗材扫描单组
// export const oneScanConsumable = async (data: oneConsumableParams) => {
// try {
// const res = await apiClient.post(
// '/api/v1/app/consumableScan/oneScanConsumable',
// {
// ...data,
// },
// )
// console.log('单组扫描返回结果:', res)
// return res.data
// } catch (error) {
// console.log('单组扫描出错:', error)
// }
// }
//修改耗材数量
export const updateConsumables = async (data: any) => {
console.log('🚀 ~ updateConsumables ~ data:', data)

79
src/store/modules/consumables.ts

@ -6,46 +6,43 @@ import { ref } from 'vue'
// ReactionPlate,
// Tip,
// } from '../../types/Index'
import type { PersistenceOptions } from 'pinia-plugin-persistedstate'
import type {
ConsumableGroupBase,
LittleBottleGroup,
LargeBottleGroup,
TipInfo,
ConsumablesStateMessage,
} from '../../websocket/socket'
// import type { PersistenceOptions } from 'pinia-plugin-persistedstate'
import type { ConsumablesStateMessage } from '../../websocket/socket'
export const useConsumablesStore = defineStore(
'consumables',
() => {
// 定义状态
const isLoad = ref(false)
const isLoading = ref(false)
const moveLiquids = ref<TipInfo[]>([])
const plates = ref<ConsumableGroupBase[]>([])
const bufferLittles = ref<LittleBottleGroup[]>([])
const bufferBig = ref<LargeBottleGroup[]>([])
// const isLoad = ref(false)
// const moveLiquids = ref<TipInfo[]>([])
// const plates = ref<ConsumableGroupBase[]>([])
// const bufferLittles = ref<LittleBottleGroup[]>([])
// const bufferBig = ref<LargeBottleGroup[]>([])
const consumableData = ref<ConsumablesStateMessage['data']>({
tips: [{ tipNum: 0 }, { tipNum: 0 }, { tipNum: 0 }],
reactionPlateGroup: Array.from({length: 6},() => ({num: 0, isInstall: false})),
littBottleGroup: Array.from({length: 6},() => ({num: 0, isInstall: false})),
larBottleGroup: Array.from({length: 6},() => ({num: 0,isInstall: false})),
})
//id卡是否插入
const isIdCardInserted = ref(false)
const wasteStatus = ref(false)
// 设置数据的 action
function setConsumablesData(data: ConsumablesStateMessage['data']) {
isLoad.value = true // 设置为已加载状态
plates.value = data.reactionPlateGroup
bufferLittles.value = data.littBottleGroup
bufferBig.value = data.larBottleGroup
moveLiquids.value = data.tips
// isLoad.value = true // 设置为已加载状态
consumableData.value = data
}
// 清除数据的 action
function resetConsumablesData() {
isLoad.value = false
isLoading.value = false
moveLiquids.value = []
plates.value = []
bufferLittles.value = []
bufferBig.value = []
function updateTipNum(index: number, num: number) {
if (index < consumableData.value.tips.length && num >= 0) {
consumableData.value.tips[index].tipNum = num
}
}
function updateReactionPlateNum(index: number, num: number) {
if (index < consumableData.value.reactionPlateGroup.length && num >= 0) {
consumableData.value.reactionPlateGroup[index].num = num
}
}
function updateWasteStatus(status: boolean) {
wasteStatus.value = status
}
@ -54,24 +51,22 @@ export const useConsumablesStore = defineStore(
}
return {
isLoad,
isLoading,
moveLiquids,
plates,
bufferLittles,
bufferBig,
updateIdCardStatus,
isIdCardInserted,
consumableData,
setConsumablesData,
resetConsumablesData,
updateIdCardStatus,
updateReactionPlateNum,
updateTipNum,
updateWasteStatus,
wasteStatus,
}
},
{
persist: <PersistenceOptions>{
key: 'consumablesStore',
storage: localStorage,
},
},
// {
// persist: <PersistenceOptions>{
// key: 'consumablesStore',
// storage: localStorage,
// },
// },
)

22
src/websocket/socket.ts

@ -172,27 +172,28 @@ interface IncubationPlateStateMessage extends BaseMessage {
// ��材组信息基础接口
interface ConsumableGroupBase {
projId: number | null
projName: string | null
projShortName: string | null
projId: number
projName: string
projShortName: string
lotId: string
color: string
num: number
isInstall: boolean
reserveNum: number
}
export interface ReactionPlateGroup extends Partial<ConsumableGroupBase> {}
// 小缓冲液接口
interface LittleBottleGroup extends ConsumableGroupBase {
type: string | null
}
interface LittleBottleGroup extends Partial<ConsumableGroupBase> {}
// 大缓冲液接口
interface LargeBottleGroup extends ConsumableGroupBase {
isInstall: boolean
}
interface LargeBottleGroup extends Partial<ConsumableGroupBase> {}
// Tips信息接口
interface TipInfo {
tipNum: number
totalNum?: number
}
// 耗材状态消息接口
@ -201,9 +202,8 @@ interface ConsumablesStateMessage extends BaseMessage {
messageType: 'Report'
dataType: 'ConsumablesState'
data: {
scanDate: number
tips: TipInfo[]
reactionPlateGroup: ConsumableGroupBase[]
reactionPlateGroup: ReactionPlateGroup[]
littBottleGroup: LittleBottleGroup[]
larBottleGroup: LargeBottleGroup[]
}

11
tsconfig.app.json

@ -1,7 +1,7 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"composite":true,
"composite": true,
"target": "ES2020",
"useDefineForClassFields": true,
"module": "ESNext",
@ -24,7 +24,12 @@
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
},
}
},
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"],
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"src/utils/longPressDirective.ts"
]
}
Loading…
Cancel
Save