Initial commit of akmon project
This commit is contained in:
94
pages/ec/nurse/bulk-entry.uvue
Normal file
94
pages/ec/nurse/bulk-entry.uvue
Normal file
@@ -0,0 +1,94 @@
|
||||
<!-- 批量体征录入 - uts-android 兼容版 -->
|
||||
<template>
|
||||
<view class="bulk-entry">
|
||||
<view class="header">
|
||||
<text class="header-title">批量体征录入</text>
|
||||
</view>
|
||||
<form @submit="onSubmit">
|
||||
<view v-for="(item, idx) in formList" :key="idx" class="form-group">
|
||||
<text class="form-label">患者</text>
|
||||
<button class="picker-btn" @click="showElderActionSheet(idx)">
|
||||
<text class="picker-text">{{ item.elder_name || '请选择患者' }}</text>
|
||||
</button>
|
||||
<text class="form-label">血压</text>
|
||||
<input class="form-input" v-model="item.blood_pressure" placeholder="如 120/80" />
|
||||
<text class="form-label">心率</text>
|
||||
<input class="form-input" v-model.number="item.heart_rate" type="number" placeholder="如 75" />
|
||||
<text class="form-label">体温</text>
|
||||
<input class="form-input" v-model.number="item.temperature" type="number" placeholder="如 36.5" />
|
||||
<text class="form-label">血糖</text>
|
||||
<input class="form-input" v-model.number="item.blood_sugar" type="number" placeholder="如 5.6" />
|
||||
<text class="form-label">血氧</text>
|
||||
<input class="form-input" v-model.number="item.oxygen_saturation" type="number" placeholder="如 98" />
|
||||
<text class="form-label">记录者</text>
|
||||
<input class="form-input" v-model="item.recorded_by" placeholder="请输入记录者姓名" />
|
||||
<text class="form-label">备注</text>
|
||||
<textarea class="form-textarea" v-model="item.notes" placeholder="可填写备注" />
|
||||
<button class="remove-btn" @click.prevent="removeItem(idx)"><text class="btn-text">移除</text></button>
|
||||
</view>
|
||||
<button class="add-btn" @click.prevent="addItem"><text class="btn-text">添加一行</text></button>
|
||||
<button class="submit-btn" form-type="submit"><text class="btn-text">批量提交</text></button>
|
||||
</form>
|
||||
</view>
|
||||
</template>
|
||||
<script setup lang="uts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import supa from '@/components/supadb/aksupainstance.uts'
|
||||
const elders = ref<any[]>([])
|
||||
const formList = ref<any[]>([getEmptyItem()])
|
||||
function getEmptyItem() {
|
||||
return { elder_id: '', elder_name: '', blood_pressure: '', heart_rate: 0, temperature: 0, blood_sugar: 0, oxygen_saturation: 0, recorded_by: '', notes: '' }
|
||||
}
|
||||
onMounted(async () => {
|
||||
const result = await supa.from('ec_elders').select('id,name').eq('status','active').order('room_number',{ascending:true}).execute()
|
||||
if (result.data) elders.value = result.data
|
||||
})
|
||||
const showElderActionSheet = (idx:number) => {
|
||||
const options = elders.value.map(e => e.name)
|
||||
uni.showActionSheet({
|
||||
itemList: options,
|
||||
success: (res:any) => {
|
||||
formList.value[idx].elder_id = elders.value[res.tapIndex].id
|
||||
formList.value[idx].elder_name = elders.value[res.tapIndex].name
|
||||
}
|
||||
})
|
||||
}
|
||||
const addItem = () => { formList.value.push(getEmptyItem()) }
|
||||
const removeItem = (idx:number) => { if(formList.value.length>1)formList.value.splice(idx,1) }
|
||||
const onSubmit = async () => {
|
||||
const validList = formList.value.filter(i=>i.elder_id)
|
||||
if (validList.length === 0) {
|
||||
uni.showToast({ title: '请至少选择一位患者', icon: 'none' }); return
|
||||
}
|
||||
const insertList = validList.map(i=>({
|
||||
elder_id: i.elder_id,
|
||||
blood_pressure: i.blood_pressure||'',
|
||||
heart_rate: i.heart_rate||0,
|
||||
temperature: i.temperature||0,
|
||||
blood_sugar: i.blood_sugar||0,
|
||||
oxygen_saturation: i.oxygen_saturation||0,
|
||||
recorded_by: i.recorded_by||'',
|
||||
notes: i.notes||'',
|
||||
recorded_at: new Date().toISOString()
|
||||
}))
|
||||
const result = await supa.from('ec_vital_signs').insert(insertList).execute()
|
||||
if (!result.error) {
|
||||
uni.showToast({ title: '批量提交成功', icon: 'success' }); uni.navigateBack()
|
||||
} else {
|
||||
uni.showToast({ title: '提交失败', icon: 'none' })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.bulk-entry { padding: 20px; background: #f5f5f5; min-height: 100vh; }
|
||||
.header { padding: 20px 0 10px 0; text-align: center; }
|
||||
.header-title { font-size: 22px; font-weight: bold; }
|
||||
.form-group { margin-bottom: 18px; background: #fff; border-radius: 8px; padding: 12px; }
|
||||
.form-label { font-size: 15px; color: #333; margin-bottom: 6px; display: block; }
|
||||
.picker-btn { background: none; border: none; padding: 0; text-align: left; }
|
||||
.picker-text { font-size: 15px; color: #333; padding: 8px 10px; border: 1px solid #ddd; border-radius: 6px; background-color: #f9f9f9; display: block; }
|
||||
.form-input { width: 100%; padding: 8px 10px; border: 1px solid #ddd; border-radius: 6px; font-size: 15px; background: #fff; }
|
||||
.form-textarea { width: 100%; min-height: 60px; padding: 8px 10px; border: 1px solid #ddd; border-radius: 6px; font-size: 15px; background: #fff; }
|
||||
.add-btn, .remove-btn, .submit-btn { width: 100%; padding: 12px 0; border-radius: 20px; background: #667eea; color: #fff; font-size: 16px; font-weight: bold; border: none; margin-top: 10px; }
|
||||
.btn-text { color: #fff; font-size: 16px; }
|
||||
</style>
|
||||
1123
pages/ec/nurse/dashboard.uvue
Normal file
1123
pages/ec/nurse/dashboard.uvue
Normal file
File diff suppressed because it is too large
Load Diff
101
pages/ec/nurse/follow-up.uvue
Normal file
101
pages/ec/nurse/follow-up.uvue
Normal file
@@ -0,0 +1,101 @@
|
||||
<!-- 体征跟进 - uts-android 兼容版 -->
|
||||
<template>
|
||||
<view class="follow-up">
|
||||
<view class="header">
|
||||
<text class="header-title">体征跟进</text>
|
||||
</view>
|
||||
<form @submit="onSubmit">
|
||||
<view class="form-group">
|
||||
<text class="form-label">患者</text>
|
||||
<input class="form-input" v-model="form.elder_name" disabled />
|
||||
</view>
|
||||
<view class="form-group">
|
||||
<text class="form-label">跟进内容</text>
|
||||
<textarea class="form-textarea" v-model="form.content" placeholder="请输入跟进内容" />
|
||||
</view>
|
||||
<button class="submit-btn" form-type="submit"><text class="btn-text">提交</text></button>
|
||||
</form>
|
||||
</view>
|
||||
</template>
|
||||
<script setup lang="uts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import supa from '@/components/supadb/aksupainstance.uts'
|
||||
const form = ref({ elder_id: '', elder_name: '', content: '' })
|
||||
|
||||
const onSubmit = async () => {
|
||||
if (!form.value.elder_id || !form.value.content) {
|
||||
uni.showToast({ title: '请填写完整', icon: 'none' }); return
|
||||
}
|
||||
const insertData = { ...form.value, created_at: new Date().toISOString() }
|
||||
const result = await supa.from('ec_vital_followup').insert([insertData]).execute()
|
||||
if (!result.error) {
|
||||
uni.showToast({ title: '提交成功', icon: 'success' }); uni.navigateBack()
|
||||
} else {
|
||||
uni.showToast({ title: '提交失败', icon: 'none' })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.follow-up {
|
||||
padding: 20px;
|
||||
background: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.header {
|
||||
padding: 20px 0 10px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
font-size: 15px;
|
||||
color: #333;
|
||||
margin-bottom: 6px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.form-input {
|
||||
width: 100%;
|
||||
padding: 8px 10px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 6px;
|
||||
font-size: 15px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.form-textarea {
|
||||
width: 100%;
|
||||
min-height: 60px;
|
||||
padding: 8px 10px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 6px;
|
||||
font-size: 15px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
width: 100%;
|
||||
padding: 12px 0;
|
||||
border-radius: 20px;
|
||||
background: #667eea;
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
border: none;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.btn-text {
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
||||
73
pages/ec/nurse/vital-detail.uvue
Normal file
73
pages/ec/nurse/vital-detail.uvue
Normal file
@@ -0,0 +1,73 @@
|
||||
<!-- 体征详情 - uts-android 兼容版 -->
|
||||
<template>
|
||||
<view class="vital-detail">
|
||||
<view class="header">
|
||||
<text class="header-title">体征详情</text>
|
||||
</view>
|
||||
<view class="detail-group">
|
||||
<text class="detail-label">患者</text>
|
||||
<text class="detail-value">{{ vital.elder_name }}</text>
|
||||
</view>
|
||||
<view class="detail-group"><text class="detail-label">血压</text><text
|
||||
class="detail-value">{{ vital.blood_pressure }}</text></view>
|
||||
<view class="detail-group"><text class="detail-label">心率</text><text
|
||||
class="detail-value">{{ vital.heart_rate }}</text></view>
|
||||
<view class="detail-group"><text class="detail-label">体温</text><text
|
||||
class="detail-value">{{ vital.temperature }}</text></view>
|
||||
<view class="detail-group"><text class="detail-label">血糖</text><text
|
||||
class="detail-value">{{ vital.blood_sugar }}</text></view>
|
||||
<view class="detail-group"><text class="detail-label">血氧</text><text
|
||||
class="detail-value">{{ vital.oxygen_saturation }}</text></view>
|
||||
<view class="detail-group"><text class="detail-label">记录者</text><text
|
||||
class="detail-value">{{ vital.recorded_by }}</text></view>
|
||||
<view class="detail-group"><text class="detail-label">备注</text><text
|
||||
class="detail-value">{{ vital.notes }}</text></view>
|
||||
<view class="detail-group"><text class="detail-label">记录时间</text><text
|
||||
class="detail-value">{{ vital.recorded_at }}</text></view>
|
||||
</view>
|
||||
</template>
|
||||
<script setup lang="uts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import supa from '@/components/supadb/aksupainstance.uts'
|
||||
const vital = ref<any>({})
|
||||
onMounted(async () => {
|
||||
const id = uni.getCurrentPages().pop()?.options?.id
|
||||
if (!id) return
|
||||
const result = await supa.from('ec_vital_signs').select('*').eq('id', id).single().execute()
|
||||
if (result.data) vital.value = result.data
|
||||
})
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.vital-detail {
|
||||
padding: 20px;
|
||||
background: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.header {
|
||||
padding: 20px 0 10px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.detail-group {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.detail-label {
|
||||
font-size: 15px;
|
||||
color: #666;
|
||||
margin-bottom: 2px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.detail-value {
|
||||
font-size: 16px;
|
||||
color: #222;
|
||||
font-weight: 500;
|
||||
}
|
||||
</style>
|
||||
190
pages/ec/nurse/vital-signs-entry.uvue
Normal file
190
pages/ec/nurse/vital-signs-entry.uvue
Normal file
@@ -0,0 +1,190 @@
|
||||
<!-- 体征录入表单 - uts-android 兼容版 -->
|
||||
<template>
|
||||
<view class="vital-signs-entry">
|
||||
<view class="header">
|
||||
<text class="header-title">体征录入</text>
|
||||
</view>
|
||||
<form @submit="onSubmit">
|
||||
<view class="form-group">
|
||||
<text class="form-label">患者</text>
|
||||
<button class="picker-btn" @click="showElderActionSheet">
|
||||
<text class="picker-text">{{ selectedElder?.name ?? '请选择患者' }}</text>
|
||||
</button>
|
||||
</view>
|
||||
<view class="form-group">
|
||||
<text class="form-label">血压 (mmHg)</text>
|
||||
<input class="form-input" v-model="form.blood_pressure" placeholder="如 120/80" />
|
||||
</view>
|
||||
<view class="form-group">
|
||||
<text class="form-label">心率 (bpm)</text>
|
||||
<input class="form-input" v-model.number="form.heart_rate" type="number" placeholder="如 75" />
|
||||
</view>
|
||||
<view class="form-group">
|
||||
<text class="form-label">体温 (°C)</text>
|
||||
<input class="form-input" v-model.number="form.temperature" type="number" placeholder="如 36.5" />
|
||||
</view>
|
||||
<view class="form-group">
|
||||
<text class="form-label">血糖 (mmol/L)</text>
|
||||
<input class="form-input" v-model.number="form.blood_sugar" type="number" placeholder="如 5.6" />
|
||||
</view>
|
||||
<view class="form-group">
|
||||
<text class="form-label">血氧 (%)</text>
|
||||
<input class="form-input" v-model.number="form.oxygen_saturation" type="number" placeholder="如 98" />
|
||||
</view>
|
||||
<view class="form-group">
|
||||
<text class="form-label">记录者</text>
|
||||
<input class="form-input" v-model="form.recorded_by" placeholder="请输入记录者姓名" />
|
||||
</view>
|
||||
<view class="form-group">
|
||||
<text class="form-label">备注</text>
|
||||
<textarea class="form-textarea" v-model="form.notes" placeholder="可填写备注" />
|
||||
</view>
|
||||
<button class="submit-btn" form-type="submit">
|
||||
<text class="btn-text">提交</text>
|
||||
</button>
|
||||
</form>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
import { ref } from 'vue'
|
||||
import supa from '@/components/supadb/aksupainstance.uts'
|
||||
|
||||
// 患者列表
|
||||
const elders = ref<any[]>([])
|
||||
const selectedElderIndex = ref<number>(-1)
|
||||
const selectedElder = computed(() => {
|
||||
if (selectedElderIndex.value < 0 || selectedElderIndex.value >= elders.value.length) return null
|
||||
return elders.value[selectedElderIndex.value]
|
||||
})
|
||||
|
||||
// 表单数据
|
||||
const form = ref({
|
||||
elder_id: '',
|
||||
blood_pressure: '',
|
||||
heart_rate: 0,
|
||||
temperature: 0,
|
||||
blood_sugar: 0,
|
||||
oxygen_saturation: 0,
|
||||
recorded_by: '',
|
||||
notes: ''
|
||||
})
|
||||
|
||||
// 加载患者
|
||||
onMounted(async () => {
|
||||
const result = await supa.from('ec_elders').select('id,name').eq('status','active').order('room_number',{ascending:true}).execute()
|
||||
if (result.data) elders.value = result.data
|
||||
})
|
||||
|
||||
// 选择患者
|
||||
const showElderActionSheet = () => {
|
||||
const options = elders.value.map(e => e.name)
|
||||
uni.showActionSheet({
|
||||
itemList: options,
|
||||
success: (res:any) => {
|
||||
selectedElderIndex.value = res.tapIndex
|
||||
form.value.elder_id = elders.value[res.tapIndex].id
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 表单提交
|
||||
const onSubmit = async (e:any) => {
|
||||
if (!form.value.elder_id) {
|
||||
uni.showToast({ title: '请选择患者', icon: 'none' })
|
||||
return
|
||||
}
|
||||
// 其他字段校验可补充
|
||||
const { elder_id, blood_pressure, heart_rate, temperature, blood_sugar, oxygen_saturation, recorded_by, notes } = form.value
|
||||
const insertData = {
|
||||
elder_id,
|
||||
blood_pressure: blood_pressure || '',
|
||||
heart_rate: heart_rate || 0,
|
||||
temperature: temperature || 0,
|
||||
blood_sugar: blood_sugar || 0,
|
||||
oxygen_saturation: oxygen_saturation || 0,
|
||||
recorded_by: recorded_by || '',
|
||||
notes: notes || '',
|
||||
recorded_at: new Date().toISOString()
|
||||
}
|
||||
const result = await supa.from('ec_vital_signs').insert([insertData]).execute()
|
||||
if (!result.error) {
|
||||
uni.showToast({ title: '提交成功', icon: 'success' })
|
||||
uni.navigateBack()
|
||||
} else {
|
||||
uni.showToast({ title: '提交失败', icon: 'none' })
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.vital-signs-entry {
|
||||
padding: 20px;
|
||||
background: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
.header {
|
||||
padding: 20px 0 10px 0;
|
||||
text-align: center;
|
||||
}
|
||||
.header-title {
|
||||
font-size: 22px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.form-group {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
.form-label {
|
||||
font-size: 15px;
|
||||
color: #333;
|
||||
margin-bottom: 6px;
|
||||
display: block;
|
||||
}
|
||||
.picker-btn {
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
text-align: left;
|
||||
}
|
||||
.picker-text {
|
||||
font-size: 15px;
|
||||
color: #333;
|
||||
padding: 8px 10px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 6px;
|
||||
background-color: #f9f9f9;
|
||||
display: block;
|
||||
}
|
||||
.form-input {
|
||||
width: 100%;
|
||||
padding: 8px 10px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 6px;
|
||||
font-size: 15px;
|
||||
background: #fff;
|
||||
}
|
||||
.form-textarea {
|
||||
width: 100%;
|
||||
min-height: 60px;
|
||||
padding: 8px 10px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 6px;
|
||||
font-size: 15px;
|
||||
background: #fff;
|
||||
}
|
||||
.submit-btn {
|
||||
width: 100%;
|
||||
padding: 12px 0;
|
||||
border-radius: 20px;
|
||||
background: #667eea;
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
border: none;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.btn-text {
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user