feat: 更新用户设置模块
This commit is contained in:
28
project.config.json
Normal file
28
project.config.json
Normal 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
|
||||
}
|
||||
}
|
||||
@@ -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(() => {
|
||||
|
||||
@@ -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="请选择结束时间"
|
||||
/>
|
||||
|
||||
|
||||
46
src/components/Profile/PlanPopup.vue
Normal file
46
src/components/Profile/PlanPopup.vue
Normal 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>
|
||||
@@ -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() {
|
||||
|
||||
@@ -157,7 +157,6 @@ function handleChangeSegment() {
|
||||
}
|
||||
|
||||
function deleteClick(item: IHealthRecord) {
|
||||
console.log(item)
|
||||
wx.showModal({
|
||||
title: '提示',
|
||||
content: '确定删除这条记录吗?',
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -10,3 +10,9 @@ export interface IOverview {
|
||||
value: string
|
||||
sub: string
|
||||
}
|
||||
|
||||
export interface IPlan {
|
||||
icon: string
|
||||
label: string
|
||||
done: boolean
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user