diff --git a/src/pages/Index/Regular/Consumables.vue b/src/pages/Index/Regular/Consumables.vue index 973fc07..293a06a 100644 --- a/src/pages/Index/Regular/Consumables.vue +++ b/src/pages/Index/Regular/Consumables.vue @@ -48,22 +48,27 @@
- +
@@ -76,10 +81,10 @@
+ + @@ -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([]) -// 移液盘的状态 -const moveLiquids = ref([ - { - 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([]) -// 临时状态管理小球激活数量 -const tempTipNum = ref([ - ...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([ - { - 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( - 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('SensorState', handleSensorState) socket.subscribe( @@ -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(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 } diff --git a/src/pages/Index/components/Consumables/MoveLiquidArea.vue b/src/pages/Index/components/Consumables/MoveLiquidArea.vue index dcbfb0b..a012d4b 100644 --- a/src/pages/Index/components/Consumables/MoveLiquidArea.vue +++ b/src/pages/Index/components/Consumables/MoveLiquidArea.vue @@ -4,18 +4,11 @@ 扫描耗材 - 卸载耗材
@@ -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 -
+
- @@ -138,9 +136,16 @@ - +
@@ -162,7 +167,6 @@
- diff --git a/src/pages/Index/components/Consumables/SliderAreaEx.vue b/src/pages/Index/components/Consumables/SliderAreaEx.vue index 04fe999..fdfde50 100644 --- a/src/pages/Index/components/Consumables/SliderAreaEx.vue +++ b/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; } - diff --git a/src/pages/Index/components/Consumables/SpttingPlates.vue b/src/pages/Index/components/Consumables/SpttingPlates.vue index cb15c64..d5bdec3 100644 --- a/src/pages/Index/components/Consumables/SpttingPlates.vue +++ b/src/pages/Index/components/Consumables/SpttingPlates.vue @@ -17,8 +17,10 @@
- {{ platesValue[i - 1]?.projShortName }} - {{ platesValue[i - 1]?.num }}/25 + {{ plates[i - 1]?.projShortName }} + {{ + !!plates[i - 1]?.isInstall ? `${plates[i - 1]?.num}/25` : '' + }}
@@ -27,19 +29,23 @@
-
+
@@ -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() diff --git a/src/services/Index/regular.ts b/src/services/Index/regular.ts index b89b94e..8d5768a 100644 --- a/src/services/Index/regular.ts +++ b/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) diff --git a/src/store/modules/consumables.ts b/src/store/modules/consumables.ts index c5a1efa..56f0b3a 100644 --- a/src/store/modules/consumables.ts +++ b/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([]) - const plates = ref([]) - const bufferLittles = ref([]) - const bufferBig = ref([]) + // const isLoad = ref(false) + // const moveLiquids = ref([]) + // const plates = ref([]) + // const bufferLittles = ref([]) + // const bufferBig = ref([]) + const consumableData = ref({ + 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: { - key: 'consumablesStore', - storage: localStorage, - }, - }, + // { + // persist: { + // key: 'consumablesStore', + // storage: localStorage, + // }, + // }, ) diff --git a/src/websocket/socket.ts b/src/websocket/socket.ts index cc815a1..0338853 100644 --- a/src/websocket/socket.ts +++ b/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 {} + // 小缓冲液接口 -interface LittleBottleGroup extends ConsumableGroupBase { - type: string | null -} +interface LittleBottleGroup extends Partial {} // 大缓冲液接口 -interface LargeBottleGroup extends ConsumableGroupBase { - isInstall: boolean -} +interface LargeBottleGroup extends Partial {} // 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[] } diff --git a/tsconfig.app.json b/tsconfig.app.json index 993bc05..a0fa6e2 100644 --- a/tsconfig.app.json +++ b/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" + ] }