1
This commit is contained in:
@@ -0,0 +1,356 @@
|
||||
<template>
|
||||
<hr-page page-bg="#F3F4F6" status-bg="#FFFFFF" nav-title="批量转运" @right-click="onHistory">
|
||||
<template v-slot:right>
|
||||
<text class="op-nav-act">历史</text>
|
||||
</template>
|
||||
|
||||
<view class="op-page">
|
||||
|
||||
<!-- ① 顶部:连续扫码 -->
|
||||
<hr-scan-cam :count="list.length" @scan="onScan" @manual="onManual"></hr-scan-cam>
|
||||
|
||||
<!-- ② 中部:伤员记录(唯一滚动区;死亡伤员不参与转运,故未列入) -->
|
||||
<hr-rec-list :list="list" @remove="onRemove" @clear="onClear"></hr-rec-list>
|
||||
|
||||
<!-- ③ 底部:转运表单 + 右下角悬浮提交 -->
|
||||
<view class="op-form">
|
||||
<text class="op-lb">接收医院</text>
|
||||
<view class="op-pick" @click="openHos">
|
||||
<text class="op-pick-n">{{ hospitalList[hosIdx] }}</text>
|
||||
<text :class="hospitalAvail[hosIdx] ? 'op-pick-b' : 'op-pick-b op-pick-b-no'">{{ hospitalBed[hosIdx] }}</text>
|
||||
<x-icon name="arrow-down-s-line" color="#9CA3AF" font-size="14"></x-icon>
|
||||
</view>
|
||||
|
||||
<text class="op-lb op-lb-gap">转运方式</text>
|
||||
<view class="hr-seg">
|
||||
<view v-for="(m, i) in modes" :key="i"
|
||||
:class="i == modeIdx ? 'hr-seg-i hr-seg-i-on' : 'hr-seg-i'" @click="modeIdx = i">
|
||||
<text :class="i == modeIdx ? 'op-seg-t op-seg-t-on' : 'op-seg-t'">{{ m }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<text class="op-lb op-lb-gap">随车联系人</text>
|
||||
<view class="op-foot">
|
||||
<view class="op-foot-col">
|
||||
<view class="hr-field">
|
||||
<text class="hr-field-label">姓名</text>
|
||||
<input class="hr-field-input" type="text" v-model="contactName" placeholder-style="color:#9CA3AF" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="op-foot-col op-foot-col-last">
|
||||
<view class="hr-field">
|
||||
<text class="hr-field-label">联系电话</text>
|
||||
<input class="hr-field-input" type="number" v-model="contactPhone" placeholder-style="color:#9CA3AF" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="op-send" @click="onSubmit">
|
||||
<x-icon name="check-line" color="#FFFFFF" font-size="24"></x-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 接收医院选择:hr-sheet 底部弹层(点击上方「接收医院」整行唤起) -->
|
||||
<template v-slot:overlay>
|
||||
<view v-if="hosSheet" class="hr-mask" @click="closeHos">
|
||||
<view class="hr-sheet" @click="stop">
|
||||
<view class="hr-sheet-h">
|
||||
<text class="hr-sheet-h-b">选择接收医院</text>
|
||||
<view class="hr-sheet-h-x" @click="closeHos">
|
||||
<x-icon name="close-line" color="#9CA3AF" font-size="18"></x-icon>
|
||||
</view>
|
||||
</view>
|
||||
<view v-for="(h, i) in hospitalList" :key="i" :class="hosOptClass(i)" @click="pickHospital(i)">
|
||||
<view class="os-txt">
|
||||
<text :class="hosNameClass(i)">{{ h }}</text>
|
||||
<text class="os-meta">{{ hospitalMeta[i] }}</text>
|
||||
</view>
|
||||
<text :class="hospitalAvail[i] ? 'op-pick-b' : 'op-pick-b op-pick-b-no'">{{ hospitalBed[i] }}</text>
|
||||
<x-icon v-if="i == hosIdx" name="check-line" color="#2563EB" font-size="17"></x-icon>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</hr-page>
|
||||
</template>
|
||||
|
||||
<script lang="uts" setup>
|
||||
import { ref } from 'vue'
|
||||
import { scanVictims, hospitalList, hospitalMeta, hospitalBed, hospitalAvail } from '@/mock/index.uts'
|
||||
import { HrVictim } from '@/mock/types.uts'
|
||||
import { navTo } from '@/utils/nav.uts'
|
||||
|
||||
/**
|
||||
* s44 批量转运(扫腕带 · 三段式作业页)
|
||||
* 与批量处置同构:顶部相机(点击开启)/ 中部记录列表 / 底部表单;
|
||||
* 底部换成 接收医院(hr-sheet 弹层选择)/ 转运方式 / 随车联系人。
|
||||
*/
|
||||
const modes : string[] = ['救护车 🚑', '直升机 🚁']
|
||||
const modeIdx = ref(0)
|
||||
const hosIdx = ref(0)
|
||||
const hosSheet = ref(false)
|
||||
const contactName = ref('刘伟')
|
||||
const contactPhone = ref('13800006621')
|
||||
|
||||
const list = ref<HrVictim[]>([
|
||||
scanVictims[0], scanVictims[1], scanVictims[2], scanVictims[3]
|
||||
])
|
||||
|
||||
/* ⚠ UTS 不提升函数声明,被调用的函数一律写在调用点之前 */
|
||||
|
||||
/** 把新伤员追加进列表(uvue 原地改数组不刷新,必须重建数组) */
|
||||
function push(v : HrVictim) : void {
|
||||
const arr : HrVictim[] = []
|
||||
for (let i = 0; i < list.value.length; i++) { arr.push(list.value[i]) }
|
||||
arr.push(v)
|
||||
list.value = arr
|
||||
}
|
||||
|
||||
function addByCode(code : string) : void {
|
||||
for (let i = 0; i < list.value.length; i++) {
|
||||
if (list.value[i].code == code) {
|
||||
uni.showToast({ title: '该伤员已在列表中', icon: 'none' })
|
||||
return
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < scanVictims.length; i++) {
|
||||
const v = scanVictims[i]
|
||||
if (v.code == code) {
|
||||
if (v.level == 4) {
|
||||
uni.showToast({ title: '死亡伤员不参与转运', icon: 'none' })
|
||||
return
|
||||
}
|
||||
push(v)
|
||||
uni.showToast({ title: '已加入 ' + v.name, icon: 'success' })
|
||||
return
|
||||
}
|
||||
}
|
||||
push({
|
||||
id: 'tmp_' + code, name: '未登记伤员', gender: '未知', age: 0, code: code, level: 3,
|
||||
injury: '待现场检伤补录', status: '', statusTheme: '', createdAt: ''
|
||||
} as HrVictim)
|
||||
uni.showToast({ title: '未登记腕带,已临时加入', icon: 'none' })
|
||||
}
|
||||
|
||||
function onScan(code : string) : void {
|
||||
addByCode(code)
|
||||
}
|
||||
|
||||
function onRemove(i : number) : void {
|
||||
const arr : HrVictim[] = []
|
||||
for (let k = 0; k < list.value.length; k++) {
|
||||
if (k != i) { arr.push(list.value[k]) }
|
||||
}
|
||||
list.value = arr
|
||||
}
|
||||
|
||||
function onClear() : void {
|
||||
uni.showModal({
|
||||
title: '清空列表',
|
||||
content: '将移除当前已识别的全部伤员记录,确认清空?',
|
||||
success: (res) => {
|
||||
if (res.confirm) { list.value = [] as HrVictim[] }
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function onManual() : void {
|
||||
uni.showModal({
|
||||
title: '手动输入腕带编号',
|
||||
editable: true,
|
||||
placeholderText: '如 TRIAGE-20260922-0006',
|
||||
success: (res) => {
|
||||
if (!res.confirm) { return }
|
||||
const code = res.content
|
||||
if (code == null || code == '') { return }
|
||||
addByCode(code as string)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/* ---------- 接收医院:hr-sheet 底部弹层 ---------- */
|
||||
|
||||
function openHos() : void {
|
||||
hosSheet.value = true
|
||||
}
|
||||
|
||||
function closeHos() : void {
|
||||
hosSheet.value = false
|
||||
}
|
||||
|
||||
/** 点击弹层面板本身时阻止冒泡,避免误关闭 */
|
||||
function stop() : void {
|
||||
}
|
||||
|
||||
function hosOptClass(i : number) : string {
|
||||
if (i == hospitalList.length - 1) { return 'hr-sheet-opt hr-sheet-opt-last' }
|
||||
return 'hr-sheet-opt'
|
||||
}
|
||||
|
||||
/** 弹层选项:医院名(两行式第一行,选中蓝 / 满员置灰) */
|
||||
function hosNameClass(i : number) : string {
|
||||
if (!hospitalAvail[i]) { return 'os-name os-name-dim' }
|
||||
if (i == hosIdx.value) { return 'os-name os-name-on' }
|
||||
return 'os-name'
|
||||
}
|
||||
|
||||
function pickHospital(i : number) : void {
|
||||
if (!hospitalAvail[i]) {
|
||||
uni.showToast({ title: '该医院急诊已满员,不可选择', icon: 'none' })
|
||||
return
|
||||
}
|
||||
hosIdx.value = i
|
||||
hosSheet.value = false
|
||||
}
|
||||
|
||||
function onSubmit() : void {
|
||||
if (list.value.length == 0) {
|
||||
uni.showToast({ title: '请先扫码添加伤员', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (contactName.value == '' || contactPhone.value == '') {
|
||||
uni.showToast({ title: '请填写随车联系人', icon: 'none' })
|
||||
return
|
||||
}
|
||||
uni.showLoading({ title: '提交中' })
|
||||
setTimeout(() => {
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: '已转运登记 ' + list.value.length + ' 人', icon: 'success' })
|
||||
setTimeout(() => {
|
||||
navTo('/pages/triage/transfer')
|
||||
}, 700)
|
||||
}, 700)
|
||||
}
|
||||
|
||||
function onHistory() : void {
|
||||
navTo('/pages/triage/treat-records')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.op-page {
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.op-nav-act {
|
||||
font-size: 29.2rpx;
|
||||
color: #6B7280;
|
||||
}
|
||||
|
||||
.op-form {
|
||||
background-color: #FFFFFF;
|
||||
border-top: 2rpx solid #E5E7EB;
|
||||
border-radius: 32rpx 32rpx 0rpx 0rpx;
|
||||
padding: 22rpx 32rpx 28rpx 32rpx;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.op-lb {
|
||||
font-size: 25.8rpx;
|
||||
font-weight: bold;
|
||||
color: #6B7280;
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
.op-lb-gap {
|
||||
margin-top: 18rpx;
|
||||
}
|
||||
|
||||
/* 接收医院:折叠字段(点击整行唤起 hr-sheet 弹层) */
|
||||
.op-pick {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
background-color: #F9FAFB;
|
||||
border: 2rpx solid #E5E7EB;
|
||||
border-radius: 20rpx;
|
||||
padding: 20rpx 24rpx 20rpx 24rpx;
|
||||
}
|
||||
|
||||
.op-pick-n {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #1F2937;
|
||||
}
|
||||
|
||||
.op-pick-b {
|
||||
font-size: 22.4rpx;
|
||||
font-weight: bold;
|
||||
color: #059669;
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
|
||||
.op-pick-b-no {
|
||||
color: #DC2626;
|
||||
}
|
||||
|
||||
/* 弹层选项:左侧「医院名 + 距离/预计时间」两行 */
|
||||
.os-txt {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.os-name {
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
color: #1F2937;
|
||||
}
|
||||
|
||||
.os-name-on {
|
||||
color: #2563EB;
|
||||
}
|
||||
|
||||
.os-name-dim {
|
||||
color: #6B7280;
|
||||
}
|
||||
|
||||
.os-meta {
|
||||
font-size: 22.4rpx;
|
||||
color: #9CA3AF;
|
||||
margin-top: 6rpx;
|
||||
}
|
||||
|
||||
.op-seg-t {
|
||||
font-size: 29.2rpx;
|
||||
color: #6B7280;
|
||||
}
|
||||
|
||||
.op-seg-t-on {
|
||||
color: #2563EB;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.op-foot {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding-right: 140rpx;
|
||||
}
|
||||
|
||||
.op-foot-col {
|
||||
flex: 1;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.op-foot-col-last {
|
||||
margin-right: 0rpx;
|
||||
}
|
||||
|
||||
.op-send {
|
||||
position: absolute;
|
||||
right: 32rpx;
|
||||
bottom: 32rpx;
|
||||
width: 112rpx;
|
||||
height: 112rpx;
|
||||
border-radius: 56rpx;
|
||||
background-image: linear-gradient(to bottom right, #2563EB, #1D4ED8);
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 12rpx 36rpx rgba(37, 99, 235, 0.42);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user