feature: Sepsis Engine Refactor: Remove SIRS, Rewire qSOFA + Bundle

Frontend: GCS Entry, SOFA Display, Sepsis UI Refactor
This commit is contained in:
voltsrage
2026-06-21 03:56:27 +08:00
parent 93ea473d2b
commit bf46e6554a
48 changed files with 2686 additions and 714 deletions
@@ -0,0 +1,87 @@
import { ref, computed, unref, watch } from 'vue'
import * as clinicalApi from '@/api/clinical'
function gcsClassification(total) {
if (total <= 8) return { label: 'Severe', variant: 'critical' }
if (total <= 12) return { label: 'Moderate', variant: 'warning' }
return { label: 'Mild', variant: 'success' }
}
export function useGcs(encounterId) {
const gcs = ref(null)
const loading = ref(false)
const submitting = ref(false)
const error = ref(null)
async function fetch() {
const id = unref(encounterId)
if (!id) return
loading.value = true
error.value = null
try {
gcs.value = await clinicalApi.fetchCurrentGcs(id)
} catch (e) {
gcs.value = null
error.value = e.message
} finally {
loading.value = false
}
}
async function submit(eye, verbal, motor) {
const id = unref(encounterId)
if (!id) return
const previous = gcs.value
const optimisticTotal = eye + verbal + motor
gcs.value = {
eyeScore: eye,
verbalScore: verbal,
motorScore: motor,
totalScore: optimisticTotal,
classification: gcsClassification(optimisticTotal).label.toUpperCase(),
calculatedAt: new Date().toISOString(),
}
submitting.value = true
error.value = null
try {
await clinicalApi.submitGcsObservations(id, eye, verbal, motor)
await fetch()
} catch (e) {
gcs.value = previous
error.value = e.message
throw e
} finally {
submitting.value = false
}
}
const total = computed(() => gcs.value?.totalScore ?? null)
const components = computed(() => {
if (!gcs.value) return null
return {
eye: gcs.value.eyeScore,
verbal: gcs.value.verbalScore,
motor: gcs.value.motorScore,
}
})
const classification = computed(() => {
if (total.value == null) return null
return gcsClassification(total.value)
})
watch(() => unref(encounterId), fetch, { immediate: true })
return {
gcs,
loading,
submitting,
error,
total,
components,
classification,
fetch,
submit,
}
}
@@ -0,0 +1,67 @@
import { ref, computed, unref, watch } from 'vue'
import * as clinicalApi from '@/api/clinical'
const ORGAN_FIELDS = [
{ name: 'Respiratory', key: 'respiratoryScore' },
{ name: 'Coagulation', key: 'coagulationScore' },
{ name: 'Liver', key: 'liverScore' },
{ name: 'Cardiovascular', key: 'cardiovascularScore' },
{ name: 'CNS', key: 'cnsScore' },
{ name: 'Renal', key: 'renalScore' },
]
export function useSofa(encounterId) {
const sofa = ref(null)
const loading = ref(false)
const error = ref(null)
async function fetch() {
const id = unref(encounterId)
if (!id) return
loading.value = true
error.value = null
try {
sofa.value = await clinicalApi.fetchCurrentSofa(id)
} catch (e) {
sofa.value = null
error.value = e.message
} finally {
loading.value = false
}
}
const total = computed(() => sofa.value?.totalScore ?? null)
const delta = computed(() => sofa.value?.deltaFromBaseline ?? null)
const isBaseline = computed(() => sofa.value?.isBaseline ?? false)
const organs = computed(() => {
if (!sofa.value) return []
return ORGAN_FIELDS.map(({ name, key }) => ({
name,
score: sofa.value[key] ?? 0,
max: 4,
}))
})
const staleness = computed(() => sofa.value?.staleness ?? null)
const hasStaleData = computed(() => {
const s = staleness.value
if (!s) return false
return (s.staleComponents?.length ?? 0) > 0
|| (s.missingComponents?.length ?? 0) > 0
|| s.usedSpO2Fallback
})
watch(() => unref(encounterId), fetch, { immediate: true })
return {
sofa,
loading,
error,
total,
delta,
isBaseline,
organs,
staleness,
hasStaleData,
fetch,
}
}