forked from gzt/A8000
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
449 lines
11 KiB
449 lines
11 KiB
<template>
|
|
<div id="add-emergency-container">
|
|
<!-- 添加急诊 -->
|
|
<div class="page-header" @click="goBack">
|
|
<img class="page-header-icon" src="@/assets/Index/left.svg" />
|
|
<div class="page-header-title">添加急诊</div>
|
|
</div>
|
|
|
|
<div class="emergency-userid">
|
|
<el-row>
|
|
<el-col :span="5">
|
|
<label>样本条形码</label>
|
|
</el-col>
|
|
<el-col :span="12" style="padding-left: 20px">
|
|
<input
|
|
type="text"
|
|
placeholder="请输入样本条形码信息"
|
|
@focus="showKeyboard('sampleBarcode')"
|
|
style="width: 400px"
|
|
:value="emergencyPosition.sampleBarcode"
|
|
/>
|
|
</el-col>
|
|
</el-row>
|
|
<el-row>
|
|
<el-col :span="5">
|
|
<label>用户ID</label>
|
|
</el-col>
|
|
<el-col :span="12" style="padding-left: 20px">
|
|
<input
|
|
type="text"
|
|
placeholder="请输入用户ID信息"
|
|
@focus="showKeyboard('userid')"
|
|
:value="emergencyPosition.userid"
|
|
style="width: 400px"
|
|
readonly
|
|
/>
|
|
</el-col>
|
|
</el-row>
|
|
</div>
|
|
<hr style="height: 1px; border: none" />
|
|
<!-- 急诊项目 -->
|
|
<div class="emergency-project">
|
|
<!-- 项目选择内容,根据需要添加 -->
|
|
<div class="project-title">
|
|
<span>项目选择</span>
|
|
</div>
|
|
<div class="project-list">
|
|
<div
|
|
v-for="item in consumableStore.projectsAvailable"
|
|
:key="item.projId"
|
|
class="project-item"
|
|
:style="projectStyle(item)"
|
|
@click="selectProject(item)"
|
|
>
|
|
<span class="proj-name">{{ item.projName }}</span>
|
|
<span> {{ item.num }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="project-title">
|
|
<span>血液类型</span>
|
|
</div>
|
|
<div class="type-list">
|
|
<div
|
|
v-for="item in settingTubeStore.bloodTypes"
|
|
:key="item.key"
|
|
@click="selectBloodType(item)"
|
|
class="blood-button"
|
|
:class="{ active: emergencyPosition.bloodType === item.key }"
|
|
>
|
|
{{ item.name }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<hr style="height: 1px; border: none" />
|
|
<!-- 急诊控制 -->
|
|
<div class="emergency-btns" style="padding: 50px 0">
|
|
<el-button class="cancel-button" @click="goBack">取消</el-button>
|
|
<el-button class="ok-button" @click="confirmHandle">确定</el-button>
|
|
</div>
|
|
|
|
<!-- 键盘 -->
|
|
<transition name="slide-up">
|
|
<div class="keyboard" v-if="keyboardVisible">
|
|
<SimpleKeyboard
|
|
:input="currentInputValue"
|
|
@onChange="handleKeyboardInput"
|
|
@onKeyPress="handleKeyPress"
|
|
/>
|
|
</div>
|
|
</transition>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, onMounted, onUnmounted } from 'vue'
|
|
import { useRouter } from 'vue-router'
|
|
import { insertEmergency } from '@/services/Index/index'
|
|
import {
|
|
useEmergencyStore,
|
|
useConsumablesStore,
|
|
useDeviceStore,
|
|
useSettingTestTubeStore,
|
|
} from '@/store'
|
|
import type { AddEmergencyInfo } from '@/types/Index'
|
|
import type { BloodType, ReactionPlateGroup } from '@/websocket/socket'
|
|
import { ElMessage } from 'element-plus'
|
|
|
|
defineOptions({
|
|
name: 'EmergencyForm',
|
|
})
|
|
|
|
const consumableStore = useConsumablesStore()
|
|
const emergencyStore = useEmergencyStore()
|
|
const deviceStore = useDeviceStore()
|
|
const settingTubeStore = useSettingTestTubeStore()
|
|
|
|
const isProjectActivated = (item: ReactionPlateGroup) => {
|
|
return emergencyPosition.value.projIds.includes(item.projId!)
|
|
}
|
|
//项目选中样式及背景色
|
|
const projectStyle = (item: ReactionPlateGroup) => {
|
|
const activated = isProjectActivated(item)
|
|
if (activated) {
|
|
return {
|
|
border: 'solid 1px transparent',
|
|
backgroundColor: consumableStore.projIdColorMap[item.projId!],
|
|
color: '#FFF',
|
|
}
|
|
} else {
|
|
return {
|
|
border: `solid 1px ${consumableStore.projIdColorMap[item.projId!]}`,
|
|
backgroundColor: '#FFF',
|
|
color: consumableStore.projIdColorMap[item.projId!],
|
|
}
|
|
}
|
|
}
|
|
// 急诊位数据
|
|
const emergencyPosition = ref<AddEmergencyInfo>({
|
|
sampleBarcode: '', // 样本条形码
|
|
userid: '', // 用户ID
|
|
projIds: [], // 项目选择
|
|
bloodType: '', // 血液类型
|
|
})
|
|
|
|
// 返回事件处理
|
|
const router = useRouter()
|
|
const goBack = () => {
|
|
router.go(-1)
|
|
}
|
|
|
|
// 确认请求
|
|
const confirmHandle = async () => {
|
|
//设备运行状态不能添加急诊
|
|
if (deviceStore.deviceState.workState === 'WORKING') {
|
|
ElMessage.error('设备正在运行,无法添加急诊')
|
|
return
|
|
}
|
|
const emergencyInfo = emergencyPosition.value
|
|
if (emergencyInfo.projIds.length === 0) {
|
|
ElMessage.error('请选择项目')
|
|
return
|
|
}
|
|
if (!emergencyInfo.bloodType) {
|
|
ElMessage.error('请选择血液类型')
|
|
return
|
|
}
|
|
const res = await insertEmergency(emergencyPosition.value)
|
|
if (res && res.success) {
|
|
goBack()
|
|
} else {
|
|
res && res.data && res.data.info && ElMessage.error(res.data.info)
|
|
}
|
|
}
|
|
|
|
const selectProject = (item: ReactionPlateGroup) => {
|
|
const projectIndex = emergencyPosition.value.projIds.findIndex(
|
|
(proj) => proj === item.projId,
|
|
)
|
|
if (projectIndex > -1) {
|
|
emergencyPosition.value.projIds.splice(projectIndex, 1)
|
|
} else {
|
|
emergencyPosition.value.projIds.push(item.projId!)
|
|
}
|
|
}
|
|
|
|
const selectBloodType = (item: { key: BloodType }) => {
|
|
emergencyPosition.value.bloodType = item.key
|
|
}
|
|
|
|
// 处理回显数据
|
|
onMounted(() => {
|
|
if (!emergencyStore.emergencyInfo) {
|
|
return
|
|
}
|
|
if (
|
|
deviceStore.deviceState.workState === 'IDLE' ||
|
|
(deviceStore.deviceState.workState === 'PAUSE' &&
|
|
emergencyStore.emergencyInfo!.state === 'TO_BE_PROCESSED')
|
|
) {
|
|
emergencyPosition.value = {
|
|
sampleBarcode: emergencyStore.emergencyInfo.sampleBarcode,
|
|
userid: emergencyStore.emergencyInfo.userid,
|
|
projIds: emergencyStore.emergencyInfo.projIds,
|
|
bloodType: emergencyStore.emergencyInfo.bloodType,
|
|
}
|
|
}
|
|
})
|
|
// 键盘相关状态
|
|
const keyboardVisible = ref(false)
|
|
const currentInputValue = ref('')
|
|
const currentInputField = ref<'sampleBarcode' | 'userid' | ''>('')
|
|
|
|
// 显示键盘
|
|
const showKeyboard = (field: 'sampleBarcode' | 'userid') => {
|
|
// 清空当前输入值,避免累加
|
|
if (field == 'sampleBarcode') {
|
|
currentInputValue.value = emergencyPosition.value.sampleBarcode
|
|
}
|
|
if (field == 'userid') {
|
|
currentInputValue.value = emergencyPosition.value.userid
|
|
}
|
|
currentInputField.value = field
|
|
keyboardVisible.value = true
|
|
}
|
|
|
|
// 处理键盘输入
|
|
const handleKeyboardInput = (value: string) => {
|
|
if (!currentInputField.value) return
|
|
// 更新当前输入值
|
|
currentInputValue.value = value
|
|
// 更新对应字段的值
|
|
if (currentInputField.value === 'sampleBarcode') {
|
|
emergencyPosition.value.sampleBarcode = value
|
|
} else {
|
|
emergencyPosition.value.userid = 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
|
|
currentInputField.value = ''
|
|
currentInputValue.value = ''
|
|
}
|
|
|
|
// 在组件卸载时清理状态
|
|
onUnmounted(() => {
|
|
hideKeyboard()
|
|
})
|
|
</script>
|
|
|
|
<style lang="less" scoped>
|
|
input {
|
|
margin-bottom: 20px;
|
|
padding: 8px 5px;
|
|
border: 1px solid #ccc;
|
|
border-radius: 4px;
|
|
font-size: 32px;
|
|
transition: box-shadow 0.2s ease;
|
|
border-radius: 10px;
|
|
&::placeholder {
|
|
font-size: 32px;
|
|
font-weight: 100;
|
|
color: #d8d8d8;
|
|
}
|
|
}
|
|
|
|
label {
|
|
margin-bottom: 8px;
|
|
font-size: 32px;
|
|
font-weight: 700;
|
|
}
|
|
|
|
#add-emergency-container {
|
|
> * {
|
|
box-sizing: border-box;
|
|
}
|
|
margin: 0;
|
|
padding: 0;
|
|
position: relative;
|
|
height: 100%;
|
|
width: 100%;
|
|
background-color: #f4f6f9;
|
|
box-sizing: border-box;
|
|
|
|
hr {
|
|
background-color: #e0e0e0;
|
|
}
|
|
|
|
.page-header {
|
|
width: 100%;
|
|
height: 100px;
|
|
display: flex;
|
|
align-items: center;
|
|
background-color: #ffffff;
|
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
|
border-radius: 8px;
|
|
|
|
.page-header-icon {
|
|
width: 16.14px;
|
|
height: 26.76px;
|
|
margin: 0 20px;
|
|
cursor: pointer;
|
|
transition: transform 0.2s ease;
|
|
|
|
&:hover {
|
|
transform: scale(1.1);
|
|
/* 放大效果 */
|
|
}
|
|
}
|
|
|
|
.page-header-title {
|
|
font-size: 36px;
|
|
font-weight: 900;
|
|
line-height: 1.2;
|
|
color: #333;
|
|
}
|
|
}
|
|
.emergency-userid {
|
|
margin-top: 40px;
|
|
margin-left: 60px;
|
|
}
|
|
.emergency-project {
|
|
width: 100%;
|
|
padding: 20px 40px;
|
|
border-radius: 10px;
|
|
margin-top: 20px;
|
|
|
|
.project-title {
|
|
width: 100%;
|
|
text-align: left;
|
|
margin-bottom: 10px;
|
|
font-size: 32px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.project-list {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
.project-item {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 5px;
|
|
padding: 8px 16px;
|
|
font-size: 24px;
|
|
border-radius: 8px;
|
|
min-width: 64px;
|
|
.proj-name {
|
|
font-weight: 600;
|
|
}
|
|
}
|
|
|
|
margin-bottom: 24px;
|
|
}
|
|
.type-list {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
padding: 10px 0 10px;
|
|
|
|
.blood-button {
|
|
border: 1px solid #5c94fe;
|
|
border-radius: 8px;
|
|
padding: 8px 16px;
|
|
color: #4a90e2;
|
|
font-size: 32px;
|
|
&.active {
|
|
border: 1px solid transparent;
|
|
background-color: #4a90e2;
|
|
color: #fff;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.emergency-btns {
|
|
width: 100%;
|
|
height: 120px;
|
|
display: flex;
|
|
margin-top: 30px;
|
|
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
|
|
.cancel-button,
|
|
.ok-button {
|
|
width: 360px;
|
|
height: 100px;
|
|
border-radius: 30px;
|
|
font-size: 36px;
|
|
font-weight: 400;
|
|
margin: 0 10px;
|
|
border: none;
|
|
}
|
|
|
|
.ok-button {
|
|
background-color: #528dfe;
|
|
color: white;
|
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.cancel-button {
|
|
background-color: #f2f2f2;
|
|
color: black;
|
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
}
|
|
}
|
|
|
|
.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;
|
|
}
|
|
// 键盘动画
|
|
.slide-up-enter-active,
|
|
.slide-up-leave-active {
|
|
transition: transform 0.3s ease;
|
|
}
|
|
.slide-up-enter-from,
|
|
.slide-up-leave-to {
|
|
transform: translateY(100%);
|
|
}
|
|
}
|
|
</style>
|