feat: 更新用户设置模块

This commit is contained in:
2026-08-25 19:50:20 +08:00
parent 98d74918a0
commit 0b9cbc9d81
10 changed files with 144 additions and 21 deletions

28
project.config.json Normal file
View File

@@ -0,0 +1,28 @@
{
"appid": "wx59440638480c6218",
"compileType": "miniprogram",
"libVersion": "3.17.1",
"packOptions": {
"ignore": [],
"include": []
},
"setting": {
"coverView": true,
"es6": true,
"postcss": true,
"minified": true,
"enhance": true,
"showShadowRootInWxmlPanel": true,
"packNpmRelationList": [],
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
}
},
"condition": {},
"editorSetting": {
"tabIndent": "insertSpaces",
"tabSize": 2
}
}

View File

@@ -1,11 +1,14 @@
<script setup lang="ts">
import { onLaunch, onShow, onHide } from "@dcloudio/uni-app";
import { getOverview, saveOverview } from "@/utils/profile";
import { getOverview, saveOverview, getPlan, savePlan } from "@/utils/profile";
onLaunch(() => {
if (getOverview().length === 0) {
saveOverview(['weight', 'sleep', 'sport', 'bloodPressure'])
}
if (getPlan().length === 0) {
savePlan(['weight', 'sleep', 'sport', 'bloodPressure'])
}
console.log("App Launch");
});
onShow(() => {

View File

@@ -77,6 +77,7 @@
<wd-datetime-picker
v-model="recordStore.sleepForm.startTime"
v-model:visible="showStartPicker"
:max-date="Date.now()"
placeholder="请选择开始时间"
/>
@@ -84,6 +85,7 @@
<wd-datetime-picker
v-model="recordStore.sleepForm.endTime"
v-model:visible="showEndPicker"
:max-date="Date.now()"
placeholder="请选择结束时间"
/>

View File

@@ -0,0 +1,46 @@
<template>
<wd-popup
v-model="profileStore.showPlanPopup"
position="bottom"
:safe-area-inset-bottom="true"
custom-style="border-radius: 32rpx 32rpx 0 0; padding: 40rpx 32rpx"
>
<view class="mb-4 text-center text-base text-gray-700 font-semibold">
今日计划
</view>
<wd-checkbox-group v-model="profileStore.planList" type="button">
<wd-checkbox name="weight">记录体重</wd-checkbox>
<wd-checkbox name="sleep">睡眠时长8小时</wd-checkbox>
<wd-checkbox name="sport">运动30分钟</wd-checkbox>
<wd-checkbox name="bloodPressure">测量血压</wd-checkbox>
<wd-checkbox name="bloodSugar">测量血糖</wd-checkbox>
<wd-checkbox name="temperature">测量体温</wd-checkbox>
</wd-checkbox-group>
<view class="flex w-full items-center justify-evenly">
<wd-button type="info" @click="cancelClick">
取消
</wd-button>
<wd-button type="primary" @click="saveClick">
保存
</wd-button>
</view>
</wd-popup>
</template>
<script lang="ts" setup>
import { useProfileStore } from '@/store/profile'
import { savePlan } from "@/utils/profile";
const profileStore = useProfileStore()
function cancelClick() {
profileStore.showPlanPopup = false
}
function saveClick() {
savePlan(profileStore.planList)
profileStore.showPlanPopup = false
}
</script>

View File

@@ -36,6 +36,8 @@
<!-- 今日计划 -->
<wd-card title="🎯 今日计划" custom-class="!mx-2 !mb-0">
<wd-empty v-if="plans.length === 0" icon="no-content" tip="暂无计划" />
<view v-for="(plan, idx) in plans" :key="idx">
<view class="flex items-center justify-between py-2.5">
<view class="flex items-center gap-2.5">
@@ -81,8 +83,8 @@ import {getDateStr, getDayRecords, getTimeStr} from '@/utils/record'
import type { IHealthRecord } from "@/type/record";
import { onShow } from "@dcloudio/uni-app";
import appLogo from '@/static/logo.png'
import {getOverview, getProfile} from "@/utils/profile";
import type {IOverview} from "@/type/profile";
import {getOverview, getPlan, getProfile} from "@/utils/profile";
import type {IOverview, IPlan} from "@/type/profile";
const imgURL = appLogo
@@ -207,18 +209,37 @@ const plans = computed(() => {
.reduce((sum, r) => sum + (r.duration || 0), 0)
const sleepOnTime = list
.filter(r => r.type === 'sleep')
.some((r) => {
const hour = new Date(r.startTime).getHours()
return hour <= 23
})
const hasBp = list.some(r => r.type === 'bloodPressure')
.some((r) => r.duration >= 8)
const hasBloodPressure = list.some(r => r.type === 'bloodPressure')
const hasBloodSugar = list.some(r => r.type === 'bloodSugar')
const hasTemperature = list.some(r => r.type === 'temperature')
return [
{ icon: '⚖️', label: '记录体重', done: hasWeight },
{ icon: '❤️', label: '测量血压', done: hasBp },
{ icon: '🏃', label: '运动30分钟', done: sportTotal >= 30 },
{ icon: '🛏️', label: '23:00 前入睡', done: sleepOnTime },
]
const planList = getPlan()
const result = [] as IPlan[]
planList.forEach((item) => {
if (item === 'weight') {
result.push({ icon: '⚖️', label: '记录体重', done: hasWeight })
}
else if (item === 'sleep') {
result.push({ icon: '😴️', label: '睡眠时长8小时', done: sleepOnTime })
}
else if (item === 'sport') {
result.push({ icon: '🏃', label: '运动30分钟', done: sportTotal >= 30 })
}
else if (item === 'bloodPressure') {
result.push({ icon: '❤️', label: '测量血压', done: hasBloodPressure })
}
else if (item === 'bloodSugar') {
result.push({ icon: '🩸', label: '测量血糖', done: hasBloodSugar })
}
else if (item === 'temperature') {
result.push({ icon: '🌡️', label: '记录体温', done: hasTemperature })
}
})
return result
})
function handelFabClick() {

View File

@@ -157,7 +157,6 @@ function handleChangeSegment() {
}
function deleteClick(item: IHealthRecord) {
console.log(item)
wx.showModal({
title: '提示',
content: '确定删除这条记录吗?',

View File

@@ -21,9 +21,9 @@
</wd-card>
<wd-cell-group>
<wd-cell title="今日概览" is-link @click="openOverviewPopup"/>
<wd-cell title="今日计划" is-link @click="openStoragePopup"/>
<wd-cell title="存储详情" is-link @click="openStoragePopup"/>
<wd-cell size="large" title="今日概览" is-link @click="openOverviewPopup"/>
<wd-cell size="large" title="今日计划" is-link @click="openPlanPopup"/>
<wd-cell size="large" title="存储详情" is-link @click="openStoragePopup"/>
</wd-cell-group>
<profile-popup />
@@ -31,6 +31,8 @@
<storage-popup />
<overview-popup />
<plan-popup />
</view>
</template>
@@ -38,8 +40,9 @@
import ProfilePopup from "@/components/Profile/ProfilePopup.vue";
import StoragePopup from "@/components/Profile/StoragePopup.vue";
import OverviewPopup from "@/components/Profile/OverviewPopup.vue";
import PlanPopup from "@/components/Profile/PlanPopup.vue";
import { computed, ref, watch } from 'vue'
import { getOverview, getProfile } from '@/utils/profile'
import { getOverview, getPlan, getProfile } from '@/utils/profile'
import { useProfileStore } from '@/store/profile'
import type { IProfile } from "@/type/profile";
import { countRecordsByMonth, getTotalCount } from "@/utils/record";
@@ -72,6 +75,11 @@ function openOverviewPopup() {
profileStore.showOverviewPopup = true
}
function openPlanPopup() {
profileStore.planList = getPlan()
profileStore.showPlanPopup = true
}
function openStoragePopup() {
profileStore.storageStats = countRecordsByMonth()
profileStore.storageTotal = getTotalCount()

View File

@@ -7,6 +7,7 @@ export const useProfileStore = defineStore('profile', {
showProfilePopup: false,
showStoragePopup: false,
showOverviewPopup: false,
showPlanPopup: false,
profileForm: {
gender: '',
height: 0,
@@ -15,6 +16,7 @@ export const useProfileStore = defineStore('profile', {
storageStats: [] as IStats[],
storageTotal: 0,
overviewList: [] as string[],
planList: [] as string[],
isRefresh: false,
}),
actions: {

View File

@@ -10,3 +10,9 @@ export interface IOverview {
value: string
sub: string
}
export interface IPlan {
icon: string
label: string
done: boolean
}

View File

@@ -1,8 +1,8 @@
import type { IProfile } from "@/type/profile";
const PROFILE_KEY = 'user_profile'
const OVERVIEW_KEY = 'user_overview'
const PLAN_KEY = 'user_plan'
function getEmptyProfile(): IProfile {
return {
@@ -28,3 +28,11 @@ export function saveOverview(data: string[]) {
wx.setStorageSync(OVERVIEW_KEY, data)
}
export function getPlan(): string[] {
return wx.getStorageSync(PLAN_KEY) || []
}
export function savePlan(data: string[]) {
wx.setStorageSync(PLAN_KEY, data)
}