Initial commit of akmon project
This commit is contained in:
166
pages/ec/doctor/emergency.uvue
Normal file
166
pages/ec/doctor/emergency.uvue
Normal file
@@ -0,0 +1,166 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user