Browse Source

feat: 调试模式

master
guoapeng 3 months ago
parent
commit
984fa6328a
  1. 51
      src/pages/Index/Index.vue
  2. 250
      src/pages/Index/debug.vue
  3. 5
      src/router/router.ts
  4. 68
      src/services/debug/index.ts
  5. 12
      src/store/modules/useSystemStore.ts

51
src/pages/Index/Index.vue

@ -24,7 +24,7 @@
</div>
</div>
<el-header class="nav-bar">
<div class="logo">
<div class="logo" @click="handleLogoClick">
<img src="@/assets/Index/logo.png" alt="" class="logo-img"/>
</div>
<div class="nav-tabs" @click="handleTabClick">
@ -50,6 +50,14 @@
data-tab="设置"
>设置</router-link
>
<router-link
v-show="systemStore.isDebug"
to="/index/debug"
class="nav-tab-debug"
:class="{ active: currentRoute.path?.includes('debug') }"
data-tab="调试"
>调试</router-link
>
</div>
<div
v-if="deviceStore.deviceState.workState === 'IDLE'"
@ -348,8 +356,8 @@
</template>
<script setup lang="ts">
import { useRouter } from 'vue-router'
import { ref, onMounted, computed, watch } from 'vue'
import { ElDialog } from 'element-plus'
import { ref, onMounted, computed, watch, nextTick } from 'vue'
import { ElDialog, ElMessageBox } from 'element-plus'
import { Time, InitWarn, LoadingModal } from './components/Consumables'
import {
startWork,
@ -399,12 +407,49 @@ import InitSvg from '@/assets/init-device.svg'
import CloseSvg from '@/assets/close-device.svg'
import LogoutSvg from '@/assets/user-logout.svg'
import CancelSvg from '@/assets/user-cancel.svg'
import { useSystemStore } from '@/store/modules/useSystemStore.ts' // systemStore
const systemStore = useSystemStore() // 使 systemStor
const router = useRouter()
//
const currentRoute = computed(() => router.currentRoute.value)
console.log(currentRoute.value)
const logoClickCount = ref(0)
let clickTimeout: any;
const handleLogoClick = () => {
if (clickTimeout) {
clearTimeout(clickTimeout)
}
logoClickCount.value++
if (logoClickCount.value === 10) {
if (!systemStore.isDebug) {
ElMessageBox.confirm('是否进入调试模式?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
closeOnClickModal: false,
type: 'warning',
})
.then(() => {
systemStore.updateDebug()
console.log(systemStore.isDebug)
logoClickCount.value = 0 //
router.push('/index/debug')
})
.catch(() => {
logoClickCount.value = 0 //
})
}else {
systemStore.updateDebug()
}
console.log(systemStore.isDebug)
}
clickTimeout = setTimeout(() => {
logoClickCount.value = 0 //
}, 1000)
}
const selectedTab = ref(sessionStorage.getItem('selectedTab') || '常规')
const lineWidth = ref(0)

250
src/pages/Index/debug.vue

@ -0,0 +1,250 @@
<script setup lang="ts">
import { onMounted, onUnmounted, ref } from 'vue'
import { dropTipBlock, getConfig, getConfig1, startTest, submitConfig, submitConfig1, testOnce } from '@/services/debug'
import { eMessage } from '@/pages/Index/utils'
const tubeData = ref<any[]>([])
const takeTipEachTime = ref(false)
onMounted(async () => {
const res = await getConfig();
const res1 = await getConfig1();
tubeData.value = res.data.tubeExConfigs
takeTipEachTime.value = res1.data.takeTipEachTime || false
})
onUnmounted(() => {
hideKeyboard()
})
const keyboardVisible = ref(false)
const currentInputValue = ref('')
const handleKeyboardInput = (inputValue: string) => {
currentInputValue.value = inputValue;
tubeData.value[inputNum.value].repeatTimes = currentInputValue.value;
}
//
const handleKeyPress = (button: string) => {
if (button === '{enter}') {
hideKeyboard()
} else if (button === '{bksp}') {
// 退
const value = currentInputValue.value
if (value.length > 0) {
const newValue = value.slice(0, -1)
handleKeyboardInput(newValue)
}
}
}
//
const hideKeyboard = () => {
keyboardVisible.value = false
currentInputValue.value = ''
}
const inputNum = ref(0);
const showKeyboard = (index: number) => {
layout.value = numericLayout;
inputNum.value = index;
keyboardVisible.value = false
setTimeout(() => {
keyboardVisible.value = true
}, 200)
//
currentInputValue.value = tubeData.value[index].repeatTimes;
}
const layout = ref()
const numericLayout = {
default: [
'1 2 3',
'4 5 6',
'7 8 9',
'{bksp} 0 {enter}' //
],
}
const save = async () => {
//
const data = tubeData.value.filter((item) => item.repeatTimes > 10);
if (data.length) {
eMessage.error('请输入正确的试管次数');
return;
}
const res = await submitConfig({tubeExConfigs: tubeData.value.map(item => {
return {
repeatTimes: Number(item.repeatTimes) || 0
}
})});
if (res.success) {
eMessage.success('保存成功')
}
}
const start = async () => {
//
const res = await startTest();
if (res.success) {
eMessage.success('已开始测试')
}
}
const moveLiquid = [
{
label: '取一次5ul',
value: 5
},
{
label: '取一次10ul',
value: 10
}
]
const move = ref(10)
const lostTip = async () => {
const res = await dropTipBlock();
if (res.success) {
eMessage.success('操作成功')
}
}
const checkboxHandle = async () => {
const res = await submitConfig1({takeTipEachTime: takeTipEachTime.value})
if (res.success) {
eMessage.success('保存成功')
}
}
const start1 = async () => {
const res = await testOnce(move.value);
if (res.success) {
eMessage.success('已开始移液')
}
}
</script>
<template>
<div id="debug-view">
<div class="content-box">
<div class="title">一致性测试</div>
<div class="content">
<div v-for="(item, index) in tubeData" :key="index" class="tube-item">
<span>试管{{index + 1}}</span>
<el-input
style="width: 80px"
v-model="item.repeatTimes"
type="number"
@focus="showKeyboard(index)"
readonly
/>
</div>
</div>
<el-button type="primary" @click="save">保存配置</el-button>
<el-button type="primary" @click="start">开始测试</el-button>
</div>
<div class="content-box">
<div class="title">加样准确度与重复性</div>
<div class="content1">
<div>移液操作: </div>
<el-select v-model="move" style="width: 150px">
<el-option
v-for="(item, index) in moveLiquid"
:key="index"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-checkbox v-model="takeTipEachTime" @change="checkboxHandle"> 每次丢弃tip</el-checkbox>
</div>
<el-button @click="lostTip">丢弃tip</el-button>
<el-button type="primary" @click="start1">移液操作</el-button>
</div>
<!-- 键盘 -->
<transition name="slide-up">
<div class="keyboard" v-if="keyboardVisible">
<SimpleKeyboard
:input="currentInputValue"
:layout
@onChange="handleKeyboardInput"
@onKeyPress="handleKeyPress"
/>
</div>
</transition>
</div>
</template>
<style scoped lang="less">
#debug-view {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
background-color: #DDE4E9;
padding: 20px;
box-sizing: border-box;
.content-box {
margin-bottom: 20px;
box-sizing: border-box;
width: 100%;
background: #fff;
padding: 20px;
border-radius: 10px;
.content1 {
display: flex;
padding: 10px;
align-items: center;
.el-select {
margin: 0 20px;
}
}
.content {
.tube-item {
float: left;
height: 50px;
display: flex;
align-items: center;
padding: 10px 0;
box-sizing: border-box;
span {
width: 80px;
font-size: 16px;
}
}
}
.title {
font-weight: 800;
font-size: 20px;
display: flex;
align-items: center;
justify-content: flex-start;
border-bottom: 1px solid #ccc;
}
}
}
.keyboard {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 300px;
background-color: #f5f7fa;
border-top-left-radius: 16px;
border-top-right-radius: 16px;
box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.1);
z-index: 1000;
}
</style>

5
src/router/router.ts

@ -43,6 +43,11 @@ const routes = [
component: () => import('@/pages/Index/History.vue'),
},
{
path: 'debug',
name: 'debug',
component: () => import('@/pages/Index/debug.vue'),
},
{
path: 'setting',
name: 'setting',
component: () => import('@/pages/Index/Setting.vue'),

68
src/services/debug/index.ts

@ -0,0 +1,68 @@
import apiClient from '../../utils/axios'
const baseUrl = '/api/v1/engineer/experiment-consistency-testing/'
//添加急诊信息
export const getConfig = async () => {
try {
const res = await apiClient.post(baseUrl + 'getConfig')
return res.data
} catch (error) {
console.log(error)
}
}
export const submitConfig = async (params: any) => {
try {
const res = await apiClient.post(baseUrl + 'submitConfig', params)
return res.data
} catch (error) {
console.log(error)
}
}
export const startTest = async () => {
try {
const res = await apiClient.post(baseUrl + 'startTest')
return res.data
} catch (error) {
console.log(error)
}
}
const baseUrl1 = '/api/v1/engineer/liquid-absorption-and-distribution-test/'
export const getConfig1 = async () => {
try {
const res = await apiClient.post(baseUrl1 + 'getConfig')
return res.data
} catch (error) {
console.log(error)
}
}
export const submitConfig1 = async (params:any) => {
try {
const res = await apiClient.post(baseUrl1 + 'submitConfig', params)
return res.data
} catch (error) {
console.log(error)
}
}
export const dropTipBlock = async () => {
try {
const res = await apiClient.post(baseUrl1 + 'dropTipBlock')
return res.data
} catch (error) {
console.log(error)
}
}
export const testOnce = async (params: any) => {
try {
const res = await apiClient.post(baseUrl1 + 'testOnce' , params)
return res.data
} catch (error) {
console.log(error)
}
}

12
src/store/modules/useSystemStore.ts

@ -0,0 +1,12 @@
import { defineStore } from 'pinia'
export const useSystemStore = defineStore('system', {
state: () => ({
isDebug: false,
}),
actions: {
updateDebug() {
this.isDebug = !this.isDebug
}
},
})
Loading…
Cancel
Save