Browse Source

优化急诊位

dev
LiLongLong 7 months ago
parent
commit
8b2fe3ab22
  1. 61
      src/constant/index.ts
  2. 24
      src/mock/Index/Consumables.ts
  3. 4
      src/pages/Index/Index.vue
  4. 88
      src/pages/Index/Regular/Consumables.vue
  5. 21
      src/pages/Index/Regular/Emergency.vue
  6. 999
      src/pages/Index/Regular/Running.vue
  7. 2
      src/pages/Index/components/Consumables/BallGrid.vue
  8. 29
      src/pages/Index/components/Consumables/MoveLiquidArea.vue
  9. 4
      src/pages/Index/components/Consumables/SpttingPlates.vue
  10. 4
      src/router/router.ts
  11. 4
      src/store/modules/consumables.ts
  12. 2
      src/types/Index/Consumables.ts
  13. 5
      src/websocket/socket.ts

61
src/constant/index.ts

@ -1,24 +1,47 @@
export const DICT = {
import { Emergency } from '../types/Index/Emergency';
// 开发选项
export const devOptions = {
// 小瓶缓冲液对象的isInstall属性
// enable_LittleBottle_isInstall: false,
}
export const DICT = {}
//扫描状态
export const SCAN_CONSUMABLES_STATE_MAP:any[] = [
'PASS',//通过
'EMPTY',//空
'EXPIRED',//耗材过期
'MISS_REACTION_PLATE',//没有反应板夹
'MISS_LITTSB',//缺少小缓冲液
'MISS_LARBS',//缺少大缓冲液
'MISS_IDCARD',//未找到匹配的项目ID卡
'LITTSB_LOTID_MISMATCH',//小缓冲液批号不匹配
'LARBS_LOTID_MISMATCH',//大缓冲液批号不匹配
'REACTION_PLATE_2D_CODE_FORMATE_ERROR',//反应板二维码格式错误
'CODE_ERROR_PROJINFO_IS_ERROR',//代码错误,项目信息异常
'UN_SUPPORT_PROJ',//不支持的项目
export const SCAN_CONSUMABLES_STATE_MAP: any[] = [
'PASS', //通过
'EMPTY', //空
'EXPIRED', //耗材过期
'MISS_REACTION_PLATE', //没有反应板夹
'MISS_LITTSB', //缺少小缓冲液
'MISS_LARBS', //缺少大缓冲液
'MISS_IDCARD', //未找到匹配的项目ID卡
'LITTSB_LOTID_MISMATCH', //小缓冲液批号不匹配
'LARBS_LOTID_MISMATCH', //大缓冲液批号不匹配
'REACTION_PLATE_2D_CODE_FORMATE_ERROR', //反应板二维码格式错误
'CODE_ERROR_PROJINFO_IS_ERROR', //代码错误,项目信息异常
'UN_SUPPORT_PROJ', //不支持的项目
]
let scan_consumables_state_option: any = {}
SCAN_CONSUMABLES_STATE_MAP.map((el) => {
scan_consumables_state_option[el] = el
})
export const SCAN_CONSUMABLES_STATE = scan_consumables_state_option
//急诊位状态处理出错
const emergencyStateList = [
"EMPTY", //空
"TO_BE_PROCESSED", //待处理
"PENDING",//挂起
"RESOURCE_IS_READY",//资源准备好
"PROCESSING",//处理中
"PROCESS_COMPLETE", //完成
"ERROR",//异常
]
let scan_consumables_state_option:any = {}
SCAN_CONSUMABLES_STATE_MAP.map(el => {
scan_consumables_state_option[el] = el
let emergency_state_option: any = {}
emergencyStateList.map((el) => {
emergency_state_option[el] = el
})
export const SCAN_CONSUMABLES_STATE = scan_consumables_state_option;
export const EMERGENCY_STATE = emergency_state_option

24
src/mock/Index/Consumables.ts

@ -214,7 +214,7 @@ const consumablesScanResultData: ConsumablesScanResultData = Mock.mock({
lotId: '',
color: '',
num: 0,
isUse: false,
isInstall: false,
},
{
projId: 2,
@ -223,13 +223,13 @@ const consumablesScanResultData: ConsumablesScanResultData = Mock.mock({
lotId: 'FA020000',
color: '#DC143C',
num: 25,
isUse: true,
isInstall: true,
},
{
lotId: '',
color: '',
num: 0,
isUse: false,
isInstall: false,
},
{
projId: 4,
@ -238,7 +238,7 @@ const consumablesScanResultData: ConsumablesScanResultData = Mock.mock({
lotId: 'FA040000',
color: '#FF69B4',
num: 25,
isUse: true,
isInstall: true,
},
{
projId: 5,
@ -247,7 +247,7 @@ const consumablesScanResultData: ConsumablesScanResultData = Mock.mock({
lotId: 'FA050000',
color: '#FF1493',
num: 25,
isUse: true,
isInstall: true,
},
{
projId: 6,
@ -256,7 +256,7 @@ const consumablesScanResultData: ConsumablesScanResultData = Mock.mock({
lotId: 'FA060000',
color: '#C71585',
num: 25,
isUse: true,
isInstall: true,
},
],
},
@ -405,7 +405,7 @@ const consumableOneChannelData: ConsumablesOneChannel = Mock.mock({
lotId: '',
color: '',
num: 0,
isUse: false,
isInstall: false,
},
{
projId: 2,
@ -414,13 +414,13 @@ const consumableOneChannelData: ConsumablesOneChannel = Mock.mock({
lotId: 'FA020000',
color: '#DC143C',
num: 25,
isUse: true,
isInstall: true,
},
{
lotId: '',
color: '',
num: 0,
isUse: false,
isInstall: false,
},
{
projId: 4,
@ -429,7 +429,7 @@ const consumableOneChannelData: ConsumablesOneChannel = Mock.mock({
lotId: 'FA040000',
color: '#FF69B4',
num: 25,
isUse: true,
isInstall: true,
},
{
projId: 5,
@ -438,7 +438,7 @@ const consumableOneChannelData: ConsumablesOneChannel = Mock.mock({
lotId: 'FA050000',
color: '#FF1493',
num: 25,
isUse: true,
isInstall: true,
},
{
projId: 6,
@ -447,7 +447,7 @@ const consumableOneChannelData: ConsumablesOneChannel = Mock.mock({
lotId: 'FA060000',
color: '#C71585',
num: 25,
isUse: true,
isInstall: true,
},
],
},

4
src/pages/Index/Index.vue

@ -50,7 +50,7 @@
<el-dropdown-menu >
<el-dropdown-item>
<img class="user-logo" src="@/assets/Index/user.svg" height="30"></img>
<button class="logout" @click="onLogout">注销</button>
<button class="logout" style="width:100px" @click="onLogout">注销</button>
</el-dropdown-item>
</el-dropdown-menu>
</template>
@ -373,7 +373,7 @@ onMounted(() => {
//
const checkInit = () => {
const hasExecutedReset = sessionStorage.getItem('deviceResetFinished');
if (hasExecutedReset === "false") {
if (!hasExecutedReset || hasExecutedReset === 'false') {
showModal.value = true;
}
};

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

@ -55,7 +55,7 @@
</div>
<div class="move-liquid-area">
<MoveLiquidArea
:isLoad="isLoad"
:isLoad="isLoadedConsumables"
:isLoading="isLoading"
:moveLiquids="moveLiquids"
:tempTipNum="tempTipNum"
@ -87,7 +87,7 @@
gridWidth="240px"
gridHeight="240px"
:activeColor="item.color"
:inUse="item.isUsed"
:inUse="item.isInstall"
/>
</div>
</div>
@ -113,21 +113,14 @@ import type {
ConsumablesStateMessage,
SensorStateMessage,
EmergencyPosStateMessage,
} from '@/websocket/socket'
import { getServerInfo } from '@/utils/getServerInfo'
import { formatScanReports } from '@/utils/errorHandler'
} from '../../../websocket/socket'
import { getServerInfo } from '../../../utils/getServerInfo'
import { formatScanReports } from '../../../utils/errorHandler'
import { ElMessage } from 'element-plus'
const { wsUrl } = getServerInfo('/api/v1/app/ws/state')
const socket = createWebSocket(wsUrl)
// const sliderValue = ref(25); //
// const totalVal = ref(50)
// const hVal = ref(10)
// const hTotal = ref(60)
// const vVal = ref(10)
// const vTotal = ref(60)
const consumableStore = useConsumablesStore()
const emergencyStore = useEmergencyStore()
const deviceStore = useDeviceStore()
@ -135,8 +128,9 @@ const deviceStore = useDeviceStore()
const currentTemperature = ref(40)
//
const wasteStatus = ref(false)
//
const isLoad = ref(false)
// ()
const isLoadedConsumables = ref(false)
// ()
const isLoading = ref(false)
//
const plates = ref<ReactionPlate[]>([])
@ -155,7 +149,7 @@ const moveLiquids = ref<LiquidState[]>([
tipNum: 0,
},
])
//
//
const showScanResults = ref(false)
interface ScanReport {
channel: number
@ -166,8 +160,7 @@ interface ScanReport {
lotId: string | null
}
const formattedReports = ref<ScanReport[]>([])
//
const isAlreadyLoad = ref(false)
//
const tempTipNum = ref<number[]>([
...moveLiquids.value.map((liquid) => liquid.tipNum),
@ -182,7 +175,7 @@ interface BufferLittle {
type?: string
projId?: number
projName?: string
isUsed?: boolean
isInstall?: boolean
}
const bufferLittles = ref<BufferLittle[]>([
{
@ -228,16 +221,17 @@ const bufferBig = ref<BottleGroup[]>(
)
//
const emergencyInfo = ref(emergencyStore.$state.emergencyInfo || {})
//
const isHandleScan = ref(false)
//
const isHandleScan = ref(false)
//
const handleConfirmScan = () => {
showScanResults.value = false
isHandleScan.value = true
if (formattedReports.value.some((report) => report.isError)) {
isLoad.value = false
isAlreadyLoad.value = false
isHandleScan.value = false
isLoadedConsumables.value = false
ElMessage.warning('存在错误,请检查耗材')
} else {
isHandleScan.value = true
}
}
//使websocket
@ -253,13 +247,14 @@ const handleSensorState = (data: SensorStateMessage['data']) => {
//
if (currentTemperature.value > 40) {
console.warn('温度过高警告')
//
}
}
//false
let hasAllConsumables = ref(false)
//
const handleConsumablesState = (data: ConsumablesStateMessage['data']) => {
if (isAlreadyLoad.value && isHandleScan.value) {
if (isHandleScan.value) {
consumableStore.setConsumablesData(data)
if (!isDragging.value) {
moveLiquids.value = data.tips
@ -267,14 +262,24 @@ const handleConsumablesState = (data: ConsumablesStateMessage['data']) => {
plates.value = data.reactionPlateGroup as ReactionPlate[]
bufferLittles.value = data.littBottleGroup as BufferLittle[]
bufferBig.value = data.larBottleGroup as BottleGroup[]
if(
(data.tips && data.tips.length ) &&
(data.reactionPlateGroup && data.reactionPlateGroup.length) &&
(data.littBottleGroup && data.littBottleGroup.length) &&
(data.larBottleGroup && data.larBottleGroup.length)
){
hasAllConsumables.value = true;
}else{
hasAllConsumables.value = false;
}
//story
consumableStore.hasAllConsumables = hasAllConsumables.value
} else {
console.log('正在拖动,不更新耗材')
}
} else {
return
}
}
// 使线
// 使线
const updatePlatesAndBuffers = ({
type,
value,
@ -295,7 +300,7 @@ const updatePlatesAndBuffers = ({
bufferLittles.value[index].num = value
}
if (type === 'BigBuf' && bufferBig.value && bufferBig.value[index]) {
bufferBig.value[index].isUse = value > 0
bufferBig.value[index].isInstall = value > 0
}
}
onMounted(() => {
@ -303,10 +308,9 @@ onMounted(() => {
startWebSocket()
socket.subscribe<SensorStateMessage>('SensorState', handleSensorState)
socket.subscribe<ConsumablesStateMessage>(
'ConsumablesStateService',
'ConsumablesState',
handleConsumablesState,
)
// getEmergencyInfo()
})
onBeforeUnmount(() => {
// 线
@ -316,14 +320,14 @@ onBeforeUnmount(() => {
}
socket.unsubscribe<SensorStateMessage>('SensorState', handleSensorState)
socket.unsubscribe<ConsumablesStateMessage>(
'ConsumablesStateService',
'ConsumablesState',
handleConsumablesState,
)
})
//
onActivated(() => {
emergencyInfo.value = emergencyStore.$state.emergencyInfo || {}
if (!isLoad.value) {
if (!isLoadedConsumables.value) {
console.log('组件被激活了')
}
})
@ -351,7 +355,7 @@ const handleIsLoad = async () => {
} catch (error) {
console.error('加载耗材失败:', error)
isLoading.value = false
isAlreadyLoad.value = false
isHandleScan.value = false
ElMessage.error('加载耗材失败')
}
}
@ -365,8 +369,7 @@ watch(isHandleScan, (newVal) => {
.littBottleGroup as BufferLittle[]
bufferBig.value = consumablesData.value.larBottleGroup as BottleGroup[]
tempTipNum.value = [...moveLiquids.value.map((liquid) => liquid.tipNum)]
isLoad.value = true
isAlreadyLoad.value = true
isLoadedConsumables.value = true
consumableStore.setConsumablesData(consumablesData.value)
}
} else {
@ -375,13 +378,9 @@ watch(isHandleScan, (newVal) => {
}
})
const handleIsUnload = () => {
isLoad.value = !isLoad.value
isLoadedConsumables.value = !isLoadedConsumables.value
isLoading.value = false
isAlreadyLoad.value = false
socket.unsubscribe<ConsumablesStateMessage>(
'ConsumablesStateService',
handleConsumablesState,
)
isHandleScan.value = false
// moveLiquids tempTipNum
moveLiquids.value = [
{ id: 1, tipNum: 0 },
@ -431,7 +430,7 @@ const handleIsUnload = () => {
color: '#4caf50',
},
]
bufferBig.value = Array.from({ length: 6 }, () => ({ num: 0, isUse: false }))
bufferBig.value = Array.from({ length: 6 }, () => ({ num: 0, isInstall: false }))
}
const isDragging = ref(false)
@ -445,6 +444,7 @@ const updateTipNum = async ({
tipNum: number
sync: boolean
}) => {
if (tipNum < 0) { return }
if (deviceStore.status === 'IDLE') {
tempTipNum.value[index] = tipNum
//

21
src/pages/Index/Regular/Emergency.vue

@ -235,14 +235,14 @@ const confirmHandle = async () => {
// return
// }
const emergencyInfo = emergencyPosition.value;
if(!emergencyInfo.sampleBarcode){
ElMessage.error('请输入样本条形码');
return
}
if(!emergencyInfo.userid){
ElMessage.error('请输入用户ID');
return
}
// if(!emergencyInfo.sampleBarcode){
// ElMessage.error('');
// return
// }
// if(!emergencyInfo.userid){
// ElMessage.error('ID');
// return
// }
if (emergencyInfo.projIds.length === 0) {
ElMessage.error('请选择项目');
return
@ -270,14 +270,15 @@ const confirmHandle = async () => {
};
emergencyStore.setInfo(emergencyData);
//
// ()
router.push({
path: "/index/regular/running",
});
//TAB
sessionStorage.setItem('currentTab', '2')
} else {
console.log("🚀 ~ confirmHandle ~ res:", res)
}
};
//

999
src/pages/Index/Regular/Running.vue
File diff suppressed because it is too large
View File

2
src/pages/Index/components/Consumables/BallGrid.vue

@ -73,7 +73,7 @@ const ballStyle = (index) => {
//
const innerCircleStyle = (index) => {
const ball = props.data[index] || {}
const isActive = !!ball.isUse
const isActive = !!ball.isInstall
return {
height: `${ball.num/25.0*100}%`,
backgroundColor: isActive ? ball.color : props.innerColor,

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

@ -141,6 +141,9 @@
<InitWarn v-if="showModal" :visible="showModal" title="提示" message="请及时清理废料箱"
icon="/src/assets/Warn.svg" confirmText="确定" @close="showModal = false"
@confirm="handleConfirm" />
<InitWarn v-if="showEmergencyModal" :visible="showEmergencyModal" title="检查耗材" message="请将耗材加载完整后再添加"
icon="/src/assets/update-pin-icon.svg" confirmText="确认" @confirm="showEmergencyModal = false" />
<!--缓冲液大-->
<div class="buffer-area">
<div class="buffer-title">
@ -180,6 +183,7 @@ import { createWebSocket } from '@/websocket/socket'
import { isTubeExist } from '@/services/Index/index';
import { InitWarn } from './Warn';
import { getServerInfo } from '@/utils/getServerInfo'
import { EMERGENCY_STATE } from "@/constant"
const { wsUrl } = getServerInfo('/api/v1/app/ws/state')
const socket = createWebSocket(wsUrl)
@ -205,7 +209,6 @@ const props = defineProps({
tempTipNum: Array,
wasteStatus: Boolean,
})
let showModal = ref(false)
const handleConfirm = ()=> {
showModal.value = false;
@ -236,6 +239,7 @@ const handleEmergencyPosState = (data: EmergencyPosStateMessage['data']) => {
// data.tube.state = 'PROCESSING'
let {state} = data.tube;
// EMPTYTO_BE_PROCESSEDPROCESS_COMPLETEERROR
emergencyStore.setInfo(data.tube)
if(emergencyStateList.includes(state)){
emergencyStatus.value = true;
}else{
@ -290,14 +294,15 @@ const activeTab = ref(0)
const isActive = ref(false)
watch(
() => props.emergencyInfo,
(newVal) => {
//
if (newVal && Object.keys(newVal).length > 0) {
isActive.value = true
} else {
//
if (newVal && (newVal.state == EMERGENCY_STATE.EMPTY || newVal.state == EMERGENCY_STATE.ERROR)) {
isActive.value = false //
} else {//
isActive.value = true
}
},
{ immediate: true }, //
@ -306,8 +311,15 @@ watch(
const emergencyInfo = reactive(emergencyStore.$state.emergencyInfo)
const router = useRouter()
//
let showEmergencyModal = ref(false)
const addEmergency = () => {
if (Object.keys(emergencyInfo).length > 0) {
//
if(!consumableStore.hasAllConsumables){
showEmergencyModal.value = true;
return
}
//
if (emergencyInfo?.pos) {
//便
router.push({
path: '/index/emergency',
@ -317,6 +329,11 @@ const addEmergency = () => {
router.push('/index/emergency')
}
}
const saveIdInfo = ()=> {
}
//
const showEmergencyInfo = (item: EmergencyPosStateMessage['data']['tube']) => {
console.log('回显急诊信息', item)

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

@ -92,7 +92,7 @@ watch(
},
)
const updateSliderVal = async (plate, order) => {
if (deviceStore.status === 'IDLE') {
if (deviceStore.status === 'IDLE' && plate >= 0) {
isDragging.value = true
// eventBus.emit('confirm', {
// type: 'Plate',
@ -107,7 +107,7 @@ const updateSliderVal = async (plate, order) => {
const updateSliderEndVal = async (plate, order) => {
isDragging.value = false
if (deviceStore.status === 'IDLE') {
if (deviceStore.status === 'IDLE' && plate >= 0) {
try {
const res = await updateConsumables({ group: `CG${order}`, num: plate })
if (res.success) {

4
src/router/router.ts

@ -127,8 +127,8 @@ router.beforeEach((to, from, next) => {
return next({ path: '/notFound' }) // 权限不足,重定向到首页或者其他页面
}
}
// 如果没有问题,继续导航
next()
// next() // 删除这行,否则控制台警告
})
export default router

4
src/store/modules/consumables.ts

@ -53,6 +53,9 @@ export const useConsumablesStore = defineStore(
isIdCardInserted.value = status
}
//所有耗材都存在
let hasAllConsumables = ref(false)
return {
isLoad,
isLoading,
@ -66,6 +69,7 @@ export const useConsumablesStore = defineStore(
updateIdCardStatus,
updateWasteStatus,
wasteStatus,
hasAllConsumables
}
},
{

2
src/types/Index/Consumables.ts

@ -41,7 +41,7 @@ export interface BottleGroup {
lotId?: string
color?: string
num: number
isUse?: boolean // 仅 larBottleGroup 中存在的字段
isInstall?: boolean
}
// 耗材 接口

5
src/websocket/socket.ts

@ -187,7 +187,7 @@ interface LittleBottleGroup extends ConsumableGroupBase {
// 大缓冲液接口
interface LargeBottleGroup extends ConsumableGroupBase {
isUse: boolean
isInstall: boolean
}
// Tips信息接口
@ -199,7 +199,7 @@ interface TipInfo {
interface ConsumablesStateMessage extends BaseMessage {
type: 'ConsumablesState'
messageType: 'Report'
dataType: 'ConsumablesStateService'
dataType: 'ConsumablesState'
data: {
scanDate: number
tips: TipInfo[]
@ -246,7 +246,6 @@ class WebSocketClient {
messageType: T['dataType'],
handler: MessageHandler<T>,
): void {
console.error('messageType==', messageType)
if (!this.messageHandlers.has(messageType)) {
console.log(
'🚀 ~ WebSocketClient ~ subscribe ~ messageType:',

Loading…
Cancel
Save