Files
2026-09-24 16:25:22 +08:00

694 lines
16 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="hr-page" style="background-color:#F3F4F6">
<hr-statusbar bg="#FFFFFF"></hr-statusbar>
<!-- ============ 顶部伤情头信息 ============ -->
<view class="dh">
<view class="dh-c1"></view>
<view class="dh-top">
<view class="dh-back" @click="onBack">
<x-icon name="arrow-left-s-line" color="#FFFFFF" font-size="20"></x-icon>
</view>
<text class="dh-title">伤员详情</text>
<view class="hr-flex1"></view>
<text class="dh-state">⌖ 转运中</text>
</view>
<text class="dh-w">{{ victim.code }}</text>
<view class="dh-n">
<text class="dh-name">{{ victim.name }}</text>
<text class="dh-age">{{ victim.gender }} · {{ victim.age }} 岁</text>
<view class="hr-flex1"></view>
<view class="dh-level">
<text class="dh-level-t">{{ levelLabel }}</text>
</view>
</view>
<view class="dh-ch">
<view class="dh-chip">
<text class="dh-chip-t">⚑ 事件 EVT-20260922-014</text>
</view>
<view class="dh-chip">
<text class="dh-chip-t">⌖ 转运中</text>
</view>
</view>
<text class="dh-foot">建档 14:23 · 操作人 张明 · 现场检伤组 3 组</text>
</view>
<!-- ============ 快捷操作 ============ -->
<view class="dh-acts">
<view v-for="(a, i) in acts" :key="i" :class="i == 0 ? 'dha' : 'dha dha-sep'" @click="onAct(i)">
<view class="dha-ic" :style="{ backgroundColor: a.bg }">
<x-icon :name="a.icon" :color="a.color" font-size="32rpx"></x-icon>
</view>
<text class="dha-t" :style="{ color: a.color }">{{ a.name }}</text>
</view>
</view>
<!-- ============ 分页 Tab(基本信息 / 伤情 / 转运 / 处置) ============ -->
<x-tabs :list="tabList" :model-value="activeId" item-width="25%" height="84rpx" font-size="27rpx"
active-font-size="27rpx" title-color="#6B7280" active-title-color="#2563EB" line-color="#2563EB"
title-padding="0" :is-item-center="true" @change="onTabChange"></x-tabs>
<scroll-view class="hr-scroll" :scroll-y="true" :show-scrollbar="false">
<view class="hr-body">
<!-- ---------- 基本信息 ---------- -->
<view v-if="tab == 0">
<hr-sec title="基本信息" more="编辑 " :first="true"></hr-sec>
<view class="ig">
<view class="ig-row">
<view class="ig-it">
<text class="ig-l">身份证号</text>
<text class="ig-b">4406041991••••1234</text>
</view>
<view class="ig-it ig-it-r">
<text class="ig-l">联系电话</text>
<text class="ig-b">138••••6621</text>
</view>
</view>
<view class="ig-row">
<view class="ig-it">
<text class="ig-l">送诊时间</text>
<text class="ig-b">2026-09-22 14:35</text>
</view>
<view class="ig-it ig-it-r">
<text class="ig-l">事件来源</text>
<text class="ig-b">建筑坍塌 · 现场检伤</text>
</view>
</view>
<view class="ig-row ig-row-last">
<view class="ig-it">
<text class="ig-l">检伤分级</text>
<text class="ig-b" style="color:#B45309">{{ levelLabel }}</text>
</view>
<view class="ig-it ig-it-r">
<text class="ig-l">检伤状态</text>
<text class="ig-b">已检伤 · 转运中</text>
</view>
</view>
</view>
<hr-sec title="生命体征(最近一次 14:35" more="趋势 "></hr-sec>
<hr-card>
<view class="vs5">
<view v-for="(v, i) in vitals" :key="i"
:class="v.abnormal ? 'vc vc-warn' : 'vc'">
<text :class="v.abnormal ? 'vc-b vc-b-warn' : 'vc-b'">{{ v.value }}</text>
<text :class="v.abnormal ? 'vc-s vc-s-warn' : 'vc-s'">{{ v.unit }}</text>
</view>
</view>
<view class="dh-warn">
<x-icon name="alert-line" color="#DC2626" font-size="14"></x-icon>
<text class="dh-warn-t">脉搏偏快 · 血压偏低 · 血氧 88% 低于阈值,建议优先处置</text>
</view>
</hr-card>
</view>
<!-- ---------- 伤情 ---------- -->
<view v-if="tab == 1">
<hr-sec title="伤情标记" more="查看人体图 " :first="true"></hr-sec>
<hr-card>
<view class="dh-mks">
<view v-for="(m, i) in marks" :key="i" class="dh-mk">
<view class="dh-mk-no" :style="{ backgroundColor: m.theme == 'red' ? '#DC2626' : '#F59E0B' }">
<text class="dh-mk-no-t">{{ m.no }}</text>
</view>
<view class="hr-flex1">
<text class="dh-mk-t">{{ m.title }}</text>
<text class="dh-mk-s">{{ m.sub }}</text>
</view>
<text class="dh-mk-time">14:2{{ i + 3 }}</text>
</view>
</view>
</hr-card>
<hr-sec title="多模态记录" more=" 添加 "></hr-sec>
<hr-card>
<text class="dh-desc">{{ victim.injury }}。14:23 于坍塌现场 B 区发现,俯卧位,呼之可睁眼。移除压覆物后前臂出现活动性出血,已加压包扎。</text>
<view class="dh-upls">
<view class="dh-upl">
<x-icon name="image-line" color="#9CA3AF" font-size="19"></x-icon>
<text class="dh-upl-t">现场照片</text>
<view class="dh-upl-tag">
<text class="dh-upl-tag-t">图片 · 1.2 MB</text>
</view>
</view>
<view class="dh-upl">
<x-icon name="music-2-line" color="#9CA3AF" font-size="19"></x-icon>
<text class="dh-upl-t">现场录音</text>
<view class="dh-upl-tag">
<text class="dh-upl-tag-t">音频 · 0:42</text>
</view>
</view>
<view class="dh-upl">
<x-icon name="video-line" color="#9CA3AF" font-size="19"></x-icon>
<text class="dh-upl-t">处置视频</text>
<view class="dh-upl-tag">
<text class="dh-upl-tag-t">视频 · 0:18</text>
</view>
</view>
</view>
</hr-card>
</view>
<!-- ---------- 转运 ---------- -->
<view v-if="tab == 2">
<hr-sec title="转运信息" more="重新登记 " :first="true" @more-click="goTransfer"></hr-sec>
<view class="ig">
<view class="ig-row">
<view class="ig-it">
<text class="ig-l">接收医院</text>
<text class="ig-b">协和医院 · 急诊创伤中心</text>
</view>
<view class="ig-it ig-it-r">
<text class="ig-l">转运方式</text>
<text class="ig-b">救护车 🚑</text>
</view>
</view>
<view class="ig-row ig-row-last">
<view class="ig-it">
<text class="ig-l">转出方</text>
<text class="ig-b">张明(急救中心)</text>
</view>
<view class="ig-it ig-it-r">
<text class="ig-l">接收方</text>
<text class="ig-b">刘伟(急诊创伤中心)</text>
</view>
</view>
</view>
<hr-sec title="流转时间线" more="全部 4 条"></hr-sec>
<hr-card>
<hr-timeline :nodes="timeline"></hr-timeline>
</hr-card>
</view>
<!-- ---------- 处置 ---------- -->
<view v-if="tab == 3">
<hr-sec title="处置记录" more="全部记录 " :first="true" @more-click="goRecords"></hr-sec>
<hr-card>
<hr-timeline :nodes="treatNodes"></hr-timeline>
</hr-card>
<view class="hr-btn hr-btn-soft" style="margin-top:12px" @click="goRecords">
<x-icon name="add-line" color="#2563EB" font-size="16"></x-icon>
<text class="dh-add-t">新增处置记录</text>
</view>
</view>
<view style="height:14px"></view>
</view>
</scroll-view>
</view>
</template>
<script lang="uts" setup>
import { ref, computed } from 'vue'
import { victimList, vitalSigns, injuryMarks, victimTimeline, treatRecords } from '@/mock/index.uts'
import { HrVictim, HrVital, HrInjuryMark, HrTimelineNode } from '@/mock/types.uts'
import { navTo, navBack } from '@/utils/nav.uts'
import { TABS_ITEM_INFO, TABS_ITEM } from '@/uni_modules/tmx-ui/interface.uts'
/**
* s21 伤员详情
* 顶部伤情头信息 + 3 个快捷操作 + 4 个分页(基本信息 / 伤情 / 转运 / 处置,xTabs 驱动)。
*/
type QuickAct = { icon : string, name : string, color : string, bg : string }
const tabList : TABS_ITEM_INFO[] = [
{ title: '基本信息', id: '0' } as TABS_ITEM_INFO,
{ title: '伤情', id: '1' } as TABS_ITEM_INFO,
{ title: '转运', id: '2' } as TABS_ITEM_INFO,
{ title: '处置', id: '3' } as TABS_ITEM_INFO
]
const activeId = ref('0')
const tab = computed(() : number => {
const i = parseInt(activeId.value)
return isNaN(i) ? 0 : i
})
const victim = ref<HrVictim>(victimList[1])
const vitals = ref<HrVital[]>(vitalSigns)
const marks = ref<HrInjuryMark[]>(injuryMarks)
const timeline = ref<HrTimelineNode[]>(victimTimeline)
const treatNodes = ref<HrTimelineNode[]>(treatRecords)
const acts : QuickAct[] = [
{ icon: 'arrow-left-right-line', name: '调整分级', color: '#B45309', bg: '#FFFBEB' } as QuickAct,
{ icon: 'route-line', name: '转运登记', color: '#2563EB', bg: '#EFF6FF' } as QuickAct,
{ icon: 'phone-line', name: '联系家属', color: '#6B7280', bg: '#F3F4F6' } as QuickAct
]
// ⚠ x-tabs 的 change 下发的是 TABS_ITEM(不是 TABS_ITEM_INFO),形参类型必须一致
function onTabChange(item : TABS_ITEM, index : number) : void {
activeId.value = item.id == '' ? index.toString() : item.id
}
const levelLabel = computed(() : string => {
const l = victim.value.level
if (l == 1) { return '危重' }
if (l == 2) { return '重伤' }
if (l == 3) { return '轻伤' }
return '死亡'
})
onLoad((opt) => {
const raw = opt['id']
if (raw != null) {
const id = raw as string
for (let i = 0; i < victimList.length; i++) {
if (victimList[i].id == id) {
victim.value = victimList[i]
break
}
}
}
})
function onBack() : void {
navBack()
}
// ⚠ UTS 不提升函数声明:goTransfer 必须写在调用它的 onAct 之前
function goTransfer() : void {
navTo('/pages/triage/transfer')
}
function onAct(i : number) : void {
if (i == 0) {
uni.showModal({
title: '调整检伤分级',
content: '当前分级:' + levelLabel.value + '\n调整后需现场检伤组复核。',
cancelText: '取消',
confirmText: '去调整',
success: (res) => {
if (res.confirm) { navTo('/pages/triage/create') }
}
})
return
}
if (i == 1) { goTransfer(); return }
uni.showToast({ title: '正在呼叫登记的联系电话', icon: 'none' })
}
function goRecords() : void {
navTo('/pages/triage/treat-records')
}
</script>
<style>
.dh {
background-image: linear-gradient(to bottom right, #F59E0B, #D97706);
padding: 0rpx 28rpx 32rpx 28rpx;
position: relative;
overflow: hidden;
}
.dh-c1 {
position: absolute;
right: -80rpx;
top: -100rpx;
width: 300rpx;
height: 300rpx;
border-radius: 150rpx;
background-color: rgba(255, 255, 255, 0.10);
}
.dh-top {
display: flex;
flex-direction: row;
align-items: center;
padding-top: 12rpx;
}
.dh-back {
width: 60rpx;
height: 60rpx;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.dh-title {
font-size: 31.4rpx;
font-weight: bold;
color: #FFFFFF;
margin-left: 4rpx;
}
.dh-state {
font-size: 26.8rpx;
color: rgba(255, 255, 255, 0.92);
}
.dh-w {
font-size: 35.8rpx;
font-weight: bold;
color: #FFFFFF;
margin-top: 24rpx;
letter-spacing: 0.8rpx;
}
.dh-n {
display: flex;
flex-direction: row;
align-items: center;
margin-top: 16rpx;
}
.dh-name {
font-size: 33.6rpx;
font-weight: bold;
color: #FFFFFF;
margin-right: 16rpx;
}
.dh-age {
font-size: 29.2rpx;
color: rgba(255, 255, 255, 0.9);
}
.dh-level {
background-color: #FFFFFF;
border-radius: 40rpx;
padding: 4rpx 20rpx 4rpx 20rpx;
}
.dh-level-t {
font-size: 24.6rpx;
font-weight: bold;
color: #B45309;
}
.dh-ch {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin-top: 18rpx;
}
.dh-chip {
background-color: rgba(255, 255, 255, 0.22);
border: 2rpx solid rgba(255, 255, 255, 0.38);
border-radius: 40rpx;
padding: 4rpx 18rpx 4rpx 18rpx;
margin-right: 12rpx;
margin-bottom: 8rpx;
}
.dh-chip-t {
font-size: 23.6rpx;
font-weight: bold;
color: #FFFFFF;
}
.dh-foot {
font-size: 24.6rpx;
color: rgba(255, 255, 255, 0.9);
margin-top: 12rpx;
}
/* ---------- 快捷操作 ---------- */
.dh-acts {
display: flex;
flex-direction: row;
background-color: #FFFFFF;
border-bottom: 2rpx solid #E5E7EB;
}
.dha {
flex: 1;
flex-direction: column;
align-items: center;
padding: 22rpx 8rpx 20rpx 8rpx;
}
.dha-sep {
border-left: 2rpx solid #E5E7EB;
}
.dha-ic {
width: 68rpx;
height: 68rpx;
border-radius: 22rpx;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
margin-bottom: 10rpx;
}
.dha-ic-t {
font-size: 35.8rpx;
}
.dha-t {
font-size: 25.8rpx;
font-weight: bold;
}
/* ---------- 分页 Tab ---------- */
.tabs2 {
display: flex;
flex-direction: row;
background-color: #FFFFFF;
border-bottom: 2rpx solid #E5E7EB;
padding: 0rpx 8rpx 0rpx 8rpx;
}
.tabs2-tb {
flex: 1;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding-top: 20rpx;
padding-bottom: 18rpx;
position: relative;
}
.tabs2-t {
font-size: 28rpx;
color: #6B7280;
}
.tabs2-t-on {
color: #2563EB;
font-weight: bold;
}
.tabs2-bar {
position: absolute;
bottom: 0rpx;
width: 52rpx;
height: 5rpx;
border-radius: 4rpx;
background-color: #2563EB;
}
/* ---------- 信息栅格 ---------- */
.ig {
border: 2rpx solid #E5E7EB;
border-radius: 24rpx;
overflow: hidden;
}
.ig-row {
display: flex;
flex-direction: row;
border-bottom: 2rpx solid #E5E7EB;
}
.ig-row-last {
border-bottom-width: 0rpx;
}
.ig-it {
flex: 1;
background-color: #FFFFFF;
padding: 18rpx 20rpx 18rpx 20rpx;
}
.ig-it-r {
border-left: 2rpx solid #E5E7EB;
}
.ig-l {
font-size: 23.6rpx;
color: #9CA3AF;
}
.ig-b {
font-size: 28rpx;
font-weight: bold;
color: #1F2937;
margin-top: 6rpx;
}
/* ---------- 生命体征 ---------- */
.vs5 {
display: flex;
flex-direction: row;
}
.vc {
flex: 1;
background-color: #F9FAFB;
border: 2rpx solid #E5E7EB;
border-radius: 18rpx;
padding: 16rpx 2rpx 16rpx 2rpx;
align-items: center;
margin-right: 12rpx;
}
.vc-warn {
background-color: #FEF2F2;
border: 2rpx solid #FECACA;
}
.vc-b {
font-size: 30.2rpx;
font-weight: bold;
color: #1F2937;
}
.vc-b-warn {
color: #DC2626;
}
.vc-s {
font-size: 20.2rpx;
color: #9CA3AF;
margin-top: 6rpx;
}
.vc-s-warn {
color: #B91C1C;
font-weight: bold;
}
.dh-warn {
display: flex;
flex-direction: row;
align-items: flex-start;
margin-top: 20rpx;
}
.dh-warn-t {
flex: 1;
font-size: 24.6rpx;
color: #DC2626;
margin-left: 12rpx;
line-height: 1.5;
}
/* ---------- 伤情标记 ---------- */
.dh-mks {
flex-direction: column;
}
.dh-mk {
display: flex;
flex-direction: row;
align-items: center;
background-color: #F9FAFB;
border: 2rpx solid #E5E7EB;
border-radius: 22rpx;
padding: 20rpx 24rpx 20rpx 24rpx;
margin-bottom: 16rpx;
}
.dh-mk-no {
width: 44rpx;
height: 44rpx;
border-radius: 22rpx;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
margin-right: 20rpx;
}
.dh-mk-no-t {
font-size: 24.6rpx;
font-weight: bold;
color: #FFFFFF;
}
.dh-mk-t {
font-size: 28rpx;
font-weight: bold;
color: #1F2937;
}
.dh-mk-s {
font-size: 23.6rpx;
color: #9CA3AF;
margin-top: 4rpx;
}
.dh-mk-time {
font-size: 23.6rpx;
color: #9CA3AF;
}
/* ---------- 多模态 ---------- */
.dh-desc {
font-size: 26.8rpx;
color: #6B7280;
line-height: 1.65;
}
.dh-upls {
display: flex;
flex-direction: row;
margin-top: 20rpx;
}
.dh-upl {
width: 31%;
height: 168rpx;
border-radius: 22rpx;
background-color: #F9FAFB;
border: 2rpx solid #E5E7EB;
flex-direction: column;
align-items: center;
justify-content: center;
margin-right: 2.5%;
position: relative;
overflow: hidden;
}
.dh-upl-t {
font-size: 23.6rpx;
color: #9CA3AF;
margin-top: 8rpx;
}
.dh-upl-tag {
position: absolute;
left: 0rpx;
right: 0rpx;
bottom: 0rpx;
background-color: rgba(17, 24, 39, 0.62);
padding: 4rpx 0rpx 4rpx 0rpx;
}
.dh-upl-tag-t {
font-size: 21.2rpx;
color: #FFFFFF;
text-align: center;
}
.dh-add-t {
font-size: 31.4rpx;
font-weight: bold;
color: #2563EB;
margin-left: 12rpx;
}
</style>