This commit is contained in:
2026-09-24 16:25:22 +08:00
commit 7428184f01
1198 changed files with 314515 additions and 0 deletions
+693
View File
@@ -0,0 +1,693 @@
<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>