feat: 增加今日食谱模块

This commit is contained in:
2026-09-01 23:02:48 +08:00
parent 973b2c0705
commit cd2e7d47c4
5 changed files with 95 additions and 4 deletions

View File

@@ -0,0 +1,33 @@
<template>
<wd-popup
v-model="appStore.showRecipePopup"
position="bottom"
:lock-scroll="true"
:safe-area-inset-bottom="true"
:close-on-click-modal="true"
custom-style="border-radius: 32rpx 32rpx 0 0; padding: 40rpx 32rpx"
@close="handeClosePopup"
>
<view class="flex flex-col max-h-[70vh] overflow-y-auto">
<view class="mb-5 text-center text-[30rpx] font-semibold text-[#333] shrink-0">
{{ appStore.currentRecipe.name }}
</view>
<wd-text type="primary" :text="appStore.currentRecipe.content"/>
</view>
</wd-popup>
</template>
<script setup lang="ts">
import { useAppStore } from '@/store/app'
import { useRecordStore } from '@/store/record'
const appStore = useAppStore()
const recordStore = useRecordStore()
function handeClosePopup() {
setTimeout(() => {
recordStore.showFab = true
}, 300)
}
</script>

View File

@@ -100,6 +100,26 @@
</view> </view>
</wd-card> </wd-card>
<wd-card title="🔥 今日食谱">
<wd-empty v-if="recipeList.length === 0" icon="no-content"
:tip="errorMessage || '获取资讯失败,请检查网络连接或联系管理员'" />
<view
v-for="(item, index) in recipeList"
:key="index"
class="content-text flex flex-col py-[20rpx] border-b border-[#f5f5f5] last:border-b-0"
@click="viewRecipeClick(item)"
>
<view class="flex items-center gap-[12rpx]">
<text class="text-[30rpx] font-semibold text-[#333] truncate">
{{ item.name }}
</text>
<wd-tag v-for="(tag, index) in item.tags" :key="index" type="primary" round>{{ tag }}</wd-tag>
<wd-icon name="caret-right" size="24px"></wd-icon>
</view>
</view>
</wd-card>
<record-popup /> <record-popup />
<weight-popup /> <weight-popup />
@@ -109,6 +129,7 @@
<blood-sugar-popup /> <blood-sugar-popup />
<temperature-popup /> <temperature-popup />
<tip-popup /> <tip-popup />
<recipe-popup />
<liu-drag-button v-if="recordStore.showFab" :background="getThemePrimaryColor[appStore.themeColor]" <liu-drag-button v-if="recordStore.showFab" :background="getThemePrimaryColor[appStore.themeColor]"
@clickBtn="handelFabClick"> @clickBtn="handelFabClick">
@@ -136,9 +157,10 @@ import { getOverview, getPlan, getProfile } from "@/utils/profile";
import appLogo from '@/static/logo.png' import appLogo from '@/static/logo.png'
import type { IOverview, IPlan } from "@/type/profile"; import type { IOverview, IPlan } from "@/type/profile";
import { addSignInPoint } from "@/utils/points"; import { addSignInPoint } from "@/utils/points";
import type { ITip } from "@/type"; import type { IRecipe, ITip } from "@/type";
import TipPopup from "@/components/Home/TipPopup.vue"; import TipPopup from "@/components/Home/TipPopup.vue";
import { getTheme, getThemePrimaryColor, getThemeStyle } from "@/utils/themes"; import { getTheme, getThemePrimaryColor, getThemeStyle } from "@/utils/themes";
import RecipePopup from "@/components/Home/RecipePopup.vue";
defineOptions({ defineOptions({
name: 'Home', name: 'Home',
@@ -151,6 +173,7 @@ const appStore = useAppStore()
const todayRecords = ref<IHealthRecord[]>([]) const todayRecords = ref<IHealthRecord[]>([])
const tipList = ref<ITip[]>([]) const tipList = ref<ITip[]>([])
const recipeList = ref<IRecipe[]>([])
const errorMessage = ref<string>("") const errorMessage = ref<string>("")
const hasSignedToday = ref(checkSignedToday()) const hasSignedToday = ref(checkSignedToday())
@@ -187,6 +210,7 @@ onShow(() => {
todayRecords.value = getDayRecords(getDateStr(Date.now())) todayRecords.value = getDayRecords(getDateStr(Date.now()))
hasSignedToday.value = checkSignedToday() hasSignedToday.value = checkSignedToday()
getTipList() getTipList()
getRecipeList()
}) })
watch(() => recordStore.isRecord, () => { watch(() => recordStore.isRecord, () => {
@@ -208,12 +232,33 @@ function getTipList() {
}); });
} }
function getRecipeList() {
wx.request({
url: 'https://cxx0822.s.3q.hair/health-api/agent/recipe/latest',
method: 'GET',
header: { 'Content-Type': 'application/json' },
success: (res) => {
recipeList.value = res.data as IRecipe[]
},
fail: (err) => {
console.error('请求失败:', err);
errorMessage.value = err.errMsg
}
});
}
const viewTipClick = (item: ITip) => { const viewTipClick = (item: ITip) => {
appStore.currentTip = item appStore.currentTip = item
appStore.showTipPopup = true appStore.showTipPopup = true
recordStore.showFab = false recordStore.showFab = false
} }
const viewRecipeClick = (item: IRecipe) => {
appStore.currentRecipe = item
appStore.showRecipePopup = true
recordStore.showFab = false
}
// 今日概览 // 今日概览
const overviewItems = computed(() => { const overviewItems = computed(() => {
const list = todayRecords.value const list = todayRecords.value

View File

@@ -136,7 +136,8 @@ const currentPeriod = ref('空腹')
const periodColumns = [ const periodColumns = [
{ label: '空腹', value: '空腹' }, { label: '空腹', value: '空腹' },
{ label: '餐前', value: '餐前' }, { label: '餐前', value: '餐前' },
{ label: '餐后2h', value: '餐后2h' } { label: '餐后2h', value: '餐后2h' },
{ label: '睡前', value: '睡前' }
] ]
const weightChartData = ref({ const weightChartData = ref({

View File

@@ -1,5 +1,5 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import type { ITip } from "@/type"; import type {IRecipe, ITip} from "@/type";
export const useAppStore = defineStore('app', { export const useAppStore = defineStore('app', {
state: () => ({ state: () => ({
@@ -9,13 +9,19 @@ export const useAppStore = defineStore('app', {
recordCount: 0, recordCount: 0,
achievement: '', achievement: '',
showTipPopup: false, showTipPopup: false,
showRecipePopup: false,
themeColor: 'purple', themeColor: 'purple',
currentTip: { currentTip: {
title: '', title: '',
summary: '', summary: '',
category: '', category: '',
content: '', content: '',
} as ITip } as ITip,
currentRecipe: {
name: '',
tags: [],
content: '',
} as IRecipe,
}), }),
actions: { actions: {

View File

@@ -9,3 +9,9 @@ export interface ITip {
category: string; category: string;
content: string; content: string;
} }
export interface IRecipe {
name: string;
tags: string[];
content: string;
}