feat: 更新首页卡片功能

This commit is contained in:
2026-08-26 23:00:11 +08:00
parent bedc0af688
commit 0b94b74c88
7 changed files with 141 additions and 108 deletions

View File

@@ -1,6 +1,6 @@
<template>
<wd-popup
v-model="recordStore.showBpPopup"
v-model="recordStore.showBloodPressurePopup"
position="bottom"
:safe-area-inset-bottom="true"
:close-on-click-modal="true"
@@ -13,7 +13,7 @@
<wd-form
ref="form"
:model="recordStore.bpForm"
:model="recordStore.bloodPressureForm"
layout="horizontal"
title-width="80"
size="large"
@@ -23,7 +23,7 @@
<wd-form-item title="收缩压" prop="systolic">
<view class="flex items-center gap-2">
<wd-input-number
v-model="recordStore.bpForm.systolic"
v-model="recordStore.bloodPressureForm.systolic"
:min="60"
:max="250"
:step="1"
@@ -37,7 +37,7 @@
<wd-form-item title="舒张压" prop="diastolic">
<view class="flex items-center gap-2">
<wd-input-number
v-model="recordStore.bpForm.diastolic"
v-model="recordStore.bloodPressureForm.diastolic"
:min="40"
:max="180"
:step="1"
@@ -50,7 +50,7 @@
<wd-form-item title="心率" prop="heartRate">
<view class="flex items-center gap-2">
<wd-input-number
v-model="recordStore.bpForm.heartRate"
v-model="recordStore.bloodPressureForm.heartRate"
:min="30"
:max="220"
:step="1"
@@ -65,7 +65,7 @@
title="时间"
prop="time"
is-link
:value="formatDateTime(recordStore.bpForm.time)"
:value="formatDateTime(recordStore.bloodPressureForm.time)"
placeholder="请选择记录时间"
@click="showTimePicker = true"
/>
@@ -73,7 +73,7 @@
<!-- 备注 -->
<wd-form-item title="备注" prop="note">
<wd-input
v-model="recordStore.bpForm.note"
v-model="recordStore.bloodPressureForm.note"
:maxlength="20"
show-word-limit
placeholder="请输入备注信息"
@@ -82,17 +82,17 @@
</wd-form>
<view class="flex w-full items-center justify-evenly">
<wd-button type="info" @click="cancelBp">
<wd-button type="info" @click="cancelBloodPressure">
取消
</wd-button>
<wd-button type="primary" @click="saveBp">
<wd-button type="primary" @click="saveBloodPressure">
保存
</wd-button>
</view>
</wd-popup>
<wd-datetime-picker
v-model="recordStore.bpForm.time"
v-model="recordStore.bloodPressureForm.time"
v-model:visible="showTimePicker"
:max-date="Date.now()"
placeholder="请选择记录时间"
@@ -114,13 +114,13 @@ function handeClosePopup() {
}, 300)
}
function cancelBp() {
recordStore.showBpPopup = false
function cancelBloodPressure() {
recordStore.showBloodPressurePopup = false
handeClosePopup()
}
function saveBp() {
const { systolic, diastolic, time } = recordStore.bpForm
function saveBloodPressure() {
const { systolic, diastolic, time } = recordStore.bloodPressureForm
if (!systolic) {
uni.showToast({ title: '请输入收缩压', icon: 'none' })
@@ -139,7 +139,7 @@ function saveBp() {
return
}
recordStore.submitBp()
recordStore.submitBloodPressure()
uni.showToast({ title: '血压记录成功', icon: 'success' })
handeClosePopup()

View File

@@ -1,6 +1,6 @@
<template>
<wd-popup
v-model="recordStore.showGlucosePopup"
v-model="recordStore.showBloodSugarPopup"
position="bottom"
:safe-area-inset-bottom="true"
:close-on-click-modal="true"
@@ -13,7 +13,7 @@
<wd-form
ref="form"
:model="recordStore.glucoseForm"
:model="recordStore.bloodSugarForm"
layout="horizontal"
title-width="80"
size="large"
@@ -23,7 +23,7 @@
<wd-form-item title="血糖值" prop="value">
<view class="flex items-center gap-2">
<wd-input-number
v-model="recordStore.glucoseForm.value"
v-model="recordStore.bloodSugarForm.value"
:min="1"
:max="30"
:step="0.1"
@@ -35,7 +35,7 @@
<!-- 测量时段 -->
<wd-form-item title="时段" prop="period">
<wd-radio-group v-model="recordStore.glucoseForm.period" type="button">
<wd-radio-group v-model="recordStore.bloodSugarForm.period" type="button">
<wd-radio
v-for="item in periodColumns"
:key="item.value"
@@ -51,7 +51,7 @@
title="时间"
prop="time"
is-link
:value="formatDateTime(recordStore.glucoseForm.time)"
:value="formatDateTime(recordStore.bloodSugarForm.time)"
placeholder="请选择记录时间"
@click="showTimePicker = true"
/>
@@ -59,7 +59,7 @@
<!-- 备注 -->
<wd-form-item title="备注" prop="note">
<wd-input
v-model="recordStore.glucoseForm.note"
v-model="recordStore.bloodSugarForm.note"
:maxlength="20"
show-word-limit
placeholder="请输入备注信息"
@@ -68,17 +68,17 @@
</wd-form>
<view class="flex w-full items-center justify-evenly">
<wd-button type="info" @click="cancelGlucose">
<wd-button type="info" @click="cancelBloodSugar">
取消
</wd-button>
<wd-button type="primary" @click="saveGlucose">
<wd-button type="primary" @click="saveBloodSugar">
保存
</wd-button>
</view>
</wd-popup>
<wd-datetime-picker
v-model="recordStore.glucoseForm.time"
v-model="recordStore.bloodSugarForm.time"
v-model:visible="showTimePicker"
:max-date="Date.now()"
placeholder="请选择记录时间"
@@ -108,13 +108,13 @@ function handeClosePopup() {
}, 300)
}
function cancelGlucose() {
recordStore.showGlucosePopup = false
function cancelBloodSugar() {
recordStore.showBloodSugarPopup = false
handeClosePopup()
}
function saveGlucose() {
const { value, period, time } = recordStore.glucoseForm
function saveBloodSugar() {
const { value, period, time } = recordStore.bloodSugarForm
if (!value) {
uni.showToast({ title: '请输入血糖值', icon: 'none' })
@@ -133,7 +133,7 @@ function saveGlucose() {
return
}
recordStore.submitGlucose()
recordStore.submitBloodSugar()
uni.showToast({ title: '血糖记录成功', icon: 'success' })
handeClosePopup()

View File

@@ -38,9 +38,9 @@ const recordTypes = [
{ key: 'weight', icon: '⚖️', label: '体重', bg: 'bg-[#fff3e0]' },
{ key: 'sleep', icon: '😴', label: '睡眠', bg: 'bg-[#e3f2fd]' },
{ key: 'sport', icon: '🏃', label: '运动', bg: 'bg-[#e8f5e9]' },
{ key: 'bp', icon: '❤️', label: '血压', bg: 'bg-[#fce4ec]' },
{ key: 'glucose', icon: '🩸', label: '血糖', bg: 'bg-[#f3e5f5]' },
{ key: 'temp', icon: '🌡️', label: '体温', bg: 'bg-[#fbe9e7]' },
{ key: 'bloodPressure', icon: '❤️', label: '血压', bg: 'bg-[#fce4ec]' },
{ key: 'bloodSugar', icon: '🩸', label: '血糖', bg: 'bg-[#f3e5f5]' },
{ key: 'temperature', icon: '🌡️', label: '体温', bg: 'bg-[#fbe9e7]' },
]
function onSelect(item: { key: string, label: string }) {
@@ -55,14 +55,14 @@ function onSelect(item: { key: string, label: string }) {
else if (item.key === 'sport') {
recordStore.openSport()
}
else if (item.key === 'bp') {
recordStore.openBp()
else if (item.key === 'bloodPressure') {
recordStore.openBloodPressure()
}
else if (item.key === 'glucose') {
recordStore.openGlucose()
else if (item.key === 'bloodSugar') {
recordStore.openBloodSugar()
}
else if (item.key === 'temp') {
recordStore.openTemp()
else if (item.key === 'temperature') {
recordStore.openTemperature()
}
else {
// 其他类型暂时提示

View File

@@ -1,6 +1,6 @@
<template>
<wd-popup
v-model="recordStore.showTempPopup"
v-model="recordStore.showTemperaturePopup"
position="bottom"
:safe-area-inset-bottom="true"
:close-on-click-modal="true"
@@ -13,7 +13,7 @@
<wd-form
ref="form"
:model="recordStore.tempForm"
:model="recordStore.temperatureForm"
layout="horizontal"
title-width="80"
size="large"
@@ -23,7 +23,7 @@
<wd-form-item title="体温" prop="value">
<view class="flex items-center gap-2">
<wd-input-number
v-model="recordStore.tempForm.value"
v-model="recordStore.temperatureForm.value"
:min="35"
:max="42"
:step="0.1"
@@ -35,7 +35,7 @@
<!-- 测量部位 -->
<wd-form-item title="部位" prop="location">
<wd-radio-group v-model="recordStore.tempForm.location" type="button">
<wd-radio-group v-model="recordStore.temperatureForm.location" type="button">
<wd-radio
v-for="item in locationColumns"
:key="item.value"
@@ -51,7 +51,7 @@
title="时间"
prop="time"
is-link
:value="formatDateTime(recordStore.tempForm.time)"
:value="formatDateTime(recordStore.temperatureForm.time)"
placeholder="请选择记录时间"
@click="showTimePicker = true"
/>
@@ -59,7 +59,7 @@
<!-- 备注 -->
<wd-form-item title="备注" prop="note">
<wd-input
v-model="recordStore.tempForm.note"
v-model="recordStore.temperatureForm.note"
:maxlength="20"
show-word-limit
placeholder="请输入备注信息"
@@ -68,17 +68,17 @@
</wd-form>
<view class="flex w-full items-center justify-evenly">
<wd-button type="info" @click="cancelTemp">
<wd-button type="info" @click="cancelTemperature">
取消
</wd-button>
<wd-button type="primary" @click="saveTemp">
<wd-button type="primary" @click="saveTemperature">
保存
</wd-button>
</view>
</wd-popup>
<wd-datetime-picker
v-model="recordStore.tempForm.time"
v-model="recordStore.temperatureForm.time"
v-model:visible="showTimePicker"
:max-date="Date.now()"
placeholder="请选择记录时间"
@@ -107,13 +107,13 @@ function handeClosePopup() {
}, 300)
}
function cancelTemp() {
recordStore.showTempPopup = false
function cancelTemperature() {
recordStore.showTemperaturePopup = false
handeClosePopup()
}
function saveTemp() {
const { value, location, time } = recordStore.tempForm
function saveTemperature() {
const { value, location, time } = recordStore.temperatureForm
if (!value) {
uni.showToast({ title: '请输入体温', icon: 'none' })
@@ -132,7 +132,7 @@ function saveTemp() {
return
}
recordStore.submitTemp()
recordStore.submitTemperature()
uni.showToast({ title: '体温记录成功', icon: 'success' })
handeClosePopup()

View File

@@ -1,6 +1,6 @@
<template>
<view class="min-h-screen flex flex-col gap-3 bg-gradient-to-b from-[#a78bfa] to-[#f3e8ff]">
<view class="self-center p-1 flex items-center gap-2 text-gray-800">
<view class="min-h-screen flex flex-col bg-gradient-to-b from-[#a78bfa] to-[#f3e8ff]">
<view class="self-center py-3 flex items-center gap-2 text-gray-800">
<wd-img :width="40" :height="40" :src="imgURL" />
<view class="flex min-w-0 flex-col">
@@ -25,7 +25,10 @@
<text class="text-lg">{{ item.icon }}</text>
<text class="text-sm text-gray-400 font-medium">{{ item.label }}</text>
</view>
<wd-button size="mini" round icon="plus" :plain="true" type="primary"/>
<wd-button v-if="item.value === '未记录'"
size="mini" round icon="plus"
:plain="true" type="primary"
@click="addClick(item.type)"/>
</view>
<text class="mt-2 text-base text-gray-800 font-bold tracking-tight">
@@ -66,9 +69,9 @@
<weight-popup />
<sleep-popup />
<sport-popup />
<bp-popup />
<glucose-popup />
<temp-popup />
<blood-pressure-popup />
<blood-sugar-popup />
<temperature-popup />
<wd-fab v-if="recordStore.showFab" type="primary" :expandable="false" @click="handelFabClick" />
</view>
@@ -79,9 +82,9 @@ import RecordPopup from "@/components/Home/RecordPopup.vue";
import WeightPopup from "@/components/Home/WeightPopup.vue";
import SleepPopup from "@/components/Home/SleepPopup.vue";
import SportPopup from "@/components/Home/SportPopup.vue";
import BpPopup from "@/components/Home/BpPopup.vue";
import GlucosePopup from "@/components/Home/GlucosePopup.vue";
import TempPopup from "@/components/Home/TempPopup.vue";
import BloodPressurePopup from "@/components/Home/BloodPressurePopup.vue";
import BloodSugarPopup from "@/components/Home/BloodSugarPopup.vue";
import TemperaturePopup from "@/components/Home/TemperaturePopup.vue";
import { ref, computed, watch } from 'vue'
import { useRecordStore } from '@/store/record'
import {getDateStr, getDayRecords, getTimeStr} from '@/utils/record'
@@ -154,6 +157,7 @@ const overviewItems = computed(() => {
if (item === 'weight') {
const profile = getProfile()
result.push({
type: 'weight',
icon: '⚖️',
label: '体重',
value: weight ? `${weight.value} kg` : '未记录',
@@ -162,6 +166,7 @@ const overviewItems = computed(() => {
}
else if (item === 'sleep') {
result.push({
type: 'sleep',
icon: '😴',
label: '睡眠',
value: sleep ? `${sleep.duration}h` : '未记录',
@@ -170,14 +175,16 @@ const overviewItems = computed(() => {
}
else if (item === 'sport') {
result.push({
type: 'sport',
icon: '🏃',
label: '运动',
value: sportTotal > 0 ? `${sportTotal}min` : '0min',
value: sportTotal > 0 ? `${sportTotal}min` : '未记录',
sub: sportTotal >= 30 ? '已达标' : '目标 30min',
})
}
else if (item === 'bloodPressure') {
result.push({
type: 'bloodPressure',
icon: '❤️',
label: '血压',
value: bloodPressure ? `${bloodPressure.systolic}/${bloodPressure.diastolic}` : '未记录',
@@ -186,6 +193,7 @@ const overviewItems = computed(() => {
}
else if (item === 'bloodSugar') {
result.push({
type: 'bloodSugar',
icon: '🩸',
label: '血糖',
value: bloodSugar ? `${bloodSugar.value}mmol/L` : '未记录',
@@ -194,6 +202,7 @@ const overviewItems = computed(() => {
}
else if (item === 'temperature') {
result.push({
type: 'temperature',
icon: '🌡️',
label: '体温',
value: temperature ? `${temperature.value}` : '未记录',
@@ -247,14 +256,37 @@ const plans = computed(() => {
return result
})
function addClick(type: string) {
switch (type) {
case 'weight':
recordStore.showFab = false
recordStore.showWeightPopup = true
break
case 'sleep':
recordStore.showFab = false
recordStore.showSleepPopup = true
break
case 'sport':
recordStore.showFab = false
recordStore.showSportPopup = true
break
case 'bloodPressure':
recordStore.showFab = false
recordStore.showBloodPressurePopup = true
break
case 'bloodSugar':
recordStore.showFab = false
recordStore.showBloodSugarPopup = true
break
case 'temperature':
recordStore.showFab = false
recordStore.showTemperaturePopup = true
break
}
}
function handelFabClick() {
recordStore.showRecordPopup = true
recordStore.showFab = false
}
</script>
<style scoped lang="scss">
:deep(.wd-card:not(:last-child)) {
margin-bottom: 0;
}
</style>

View File

@@ -8,9 +8,9 @@ export const useRecordStore = defineStore('record', {
showWeightPopup: false,
showSleepPopup: false,
showSportPopup: false,
showBpPopup: false,
showGlucosePopup: false,
showTempPopup: false,
showBloodPressurePopup: false,
showBloodSugarPopup: false,
showTemperaturePopup: false,
weightForm: {
value: 0,
note: '',
@@ -29,20 +29,20 @@ export const useRecordStore = defineStore('record', {
note: '',
time: Date.now(),
},
bpForm: {
bloodPressureForm: {
systolic: 0,
diastolic: 0,
heartRate: 0,
note: '',
time: Date.now(),
},
glucoseForm: {
bloodSugarForm: {
value: 0,
period: '',
note: '',
time: Date.now(),
},
tempForm: {
temperatureForm: {
value: 36.5,
location: '',
note: '',
@@ -63,17 +63,17 @@ export const useRecordStore = defineStore('record', {
this.resetSport()
this.showSportPopup = true
},
openBp() {
this.resetBp()
this.showBpPopup = true
openBloodPressure() {
this.resetBloodPressure()
this.showBloodPressurePopup = true
},
openGlucose() {
this.resetGlucose()
this.showGlucosePopup = true
openBloodSugar() {
this.resetBloodSugar()
this.showBloodSugarPopup = true
},
openTemp() {
this.resetTemp()
this.showTempPopup = true
openTemperature() {
this.resetTemperature()
this.showTemperaturePopup = true
},
submitWeight() {
addWeight(this.weightForm.value, this.weightForm.note, this.weightForm.time)
@@ -101,35 +101,35 @@ export const useRecordStore = defineStore('record', {
this.showSportPopup = false
this.isRecord = !this.isRecord
},
submitBp() {
submitBloodPressure() {
addBloodPressure(
this.bpForm.systolic,
this.bpForm.diastolic,
this.bpForm.heartRate,
this.bpForm.note,
this.bpForm.time,
this.bloodPressureForm.systolic,
this.bloodPressureForm.diastolic,
this.bloodPressureForm.heartRate,
this.bloodPressureForm.note,
this.bloodPressureForm.time,
)
this.showBpPopup = false
this.showBloodPressurePopup = false
this.isRecord = !this.isRecord
},
submitGlucose() {
submitBloodSugar() {
addBloodSugar(
this.glucoseForm.value,
this.glucoseForm.period,
this.glucoseForm.note,
this.glucoseForm.time,
this.bloodSugarForm.value,
this.bloodSugarForm.period,
this.bloodSugarForm.note,
this.bloodSugarForm.time,
)
this.showGlucosePopup = false
this.showBloodSugarPopup = false
this.isRecord = !this.isRecord
},
submitTemp() {
submitTemperature() {
addTemperature(
this.tempForm.value,
this.tempForm.location,
this.tempForm.note,
this.tempForm.time,
this.temperatureForm.value,
this.temperatureForm.location,
this.temperatureForm.note,
this.temperatureForm.time,
)
this.showTempPopup = false
this.showTemperaturePopup = false
this.isRecord = !this.isRecord
},
resetWeight() {
@@ -141,14 +141,14 @@ export const useRecordStore = defineStore('record', {
resetSport() {
this.sportForm = { category: '跑步', duration: 30, note: '', time: Date.now() }
},
resetBp() {
this.bpForm = { systolic: 120, diastolic: 70, heartRate: 80, note: '', time: Date.now() }
resetBloodPressure() {
this.bloodPressureForm = { systolic: 120, diastolic: 70, heartRate: 80, note: '', time: Date.now() }
},
resetGlucose() {
this.glucoseForm = { value: 5.4, period: '空腹', note: '', time: Date.now() }
resetBloodSugar() {
this.bloodSugarForm = { value: 5.4, period: '空腹', note: '', time: Date.now() }
},
resetTemp() {
this.tempForm = { value: 36.5, location: '腋下', note: '', time: Date.now() }
resetTemperature() {
this.temperatureForm = { value: 36.5, location: '腋下', note: '', time: Date.now() }
},
},
})

View File

@@ -5,6 +5,7 @@ export interface IProfile {
}
export interface IOverview {
type: string
icon: string
label: string
value: string