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

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