Files
akmon/pages/ec/doctor/emergency.uvue
2026-01-20 08:04:15 +08:00

167 lines
5.4 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="emergency-page">
<view class="header">
<text class="title">急诊管理</text>
<button class="add-btn" @click="showAddEmergency"> 新建急诊</button>
</view>
<view class="stats">
<text>今日急诊: {{ stats.today }}</text>
<text>处理中: {{ stats.processing }}</text>
<text>已解决: {{ stats.resolved }}</text>
</view>
<scroll-view class="emergency-list" scroll-y="true">
<view v-for="item in emergencies" :key="item.id" class="emergency-item" :class="item.severity">
<view class="item-header">
<text class="type">{{ getTypeText(item.emergency_type) }}</text>
<text class="severity">{{ getSeverityText(item.severity) }}</text>
<text class="status">{{ getStatusText(item.status) }}</text>
</view>
<view class="item-content">
<text class="elder">患者: {{ item.elder_name }}</text>
<text class="desc">{{ item.description }}</text>
</view>
<view class="item-footer">
<text class="time">{{ formatDateTime(item.occurred_at) }}</text>
<button v-if="item.status==='active'" class="handle-btn" @click="handleEmergency(item)">处理</button>
</view>
</view>
<view v-if="emergencies.length===0" class="empty-state">
<text>暂无急诊事件</text>
</view>
</scroll-view>
</view>
</template>
<script setup lang="uts">
import { ref, onMounted } from 'vue'
import supa from '@/components/supadb/aksupainstance.uts'
import { formatDateTime } from '../types_new.uts'
type Emergency = {
id: string
appointment_id: string
elder_id: string
elder_name: string
doctor_id: string
emergency_type: string
severity: string
status: string
description: string
occurred_at: string
handled_at: string
handler_notes: string
created_at: string
updated_at: string
}
type EmergencyStats = {
today: number
processing: number
resolved: number
}
const emergencies = ref<Emergency[]>([])
const stats = ref<EmergencyStats>({ today: 0, processing: 0, resolved: 0 })
onMounted(() => {
loadEmergencies()
loadStats()
})
const loadEmergencies = async () => {
const result = await supa
.from('ec_emergencies')
.select('*')
.order('occurred_at', { ascending: false })
.limit(30)
.executeAs<Emergency[]>()
if (result.error == null && result.data != null) {
emergencies.value = result.data
}
}
const loadStats = async () => {
const todayStart = new Date()
todayStart.setHours(0,0,0,0)
const todayEnd = new Date()
todayEnd.setHours(23,59,59,999)
const todayResult = await supa
.from('ec_emergencies')
.select('*', { count: 'exact' })
.gte('occurred_at', todayStart.toISOString())
.lte('occurred_at', todayEnd.toISOString())
.executeAs<Emergency[]>()
const processingResult = await supa
.from('ec_emergencies')
.select('*', { count: 'exact' })
.eq('status', 'processing')
.executeAs<Emergency[]>()
const resolvedResult = await supa
.from('ec_emergencies')
.select('*', { count: 'exact' })
.eq('status', 'resolved')
.executeAs<Emergency[]>()
stats.value = {
today: todayResult.count ?? 0,
processing: processingResult.count ?? 0,
resolved: resolvedResult.count ?? 0
}
}
const getTypeText = (type: string): string => {
const map = new Map([
['fall', '跌倒'],
['stroke', '中风'],
['cardiac', '心脏'],
['other', '其他']
])
return map.get(type) ?? type
}
const getSeverityText = (sev: string): string => {
const map = new Map([
['low', '低'],
['medium', '中'],
['high', '高'],
['critical', '危急']
])
return map.get(sev) ?? sev
}
const getStatusText = (status: string): string => {
const map = new Map([
['active', '待处理'],
['processing', '处理中'],
['resolved', '已解决'],
['cancelled', '已取消']
])
return map.get(status) ?? status
}
const showAddEmergency = () => {
uni.navigateTo({ url: '/pages/ec/doctor/emergency-form' })
}
const handleEmergency = (item: Emergency) => {
uni.navigateTo({ url: `/pages/ec/doctor/emergency-handle?id=${item.id}` })
}
</script>
<style scoped>
.emergency-page { padding: 20px; background: #f5f5f5; min-height: 100vh; }
.header { display: flex; flex-direction: row; justify-content: space-between; align-items: center; margin-bottom: 16px; }
.title { font-size: 20px; font-weight: bold; }
.add-btn { background: #ff4757; color: #fff; border: none; border-radius: 16px; padding: 8px 18px; font-size: 15px; }
.stats { display: flex; flex-direction: row; gap: 18px; margin-bottom: 12px; }
.emergency-list { background: #fff; border-radius: 10px; }
.emergency-item { padding: 14px 10px; border-bottom: 1px solid #f0f0f0; }
.emergency-item:last-child { border-bottom: none; }
.item-header { display: flex; flex-direction: row; gap: 10px; margin-bottom: 6px; }
.type { font-size: 14px; font-weight: 600; }
.severity { font-size: 13px; color: #e67e22; }
.status { font-size: 13px; color: #3498db; }
.item-content { font-size: 13px; color: #555; margin-bottom: 6px; }
.elder { color: #888; margin-right: 10px; }
.desc { color: #555; }
.item-footer { display: flex; flex-direction: row; justify-content: space-between; align-items: center; }
.time { font-size: 12px; color: #999; }
.handle-btn { background: #27ae60; color: #fff; border: none; border-radius: 12px; padding: 6px 14px; font-size: 13px; }
.empty-state { padding: 30px 0; text-align: center; color: #999; }
</style>