From 5f3a7ca5b46744ad80a90b87d22d09c4eff59b86 Mon Sep 17 00:00:00 2001 From: Cxx0822 <1556464090@qq.com> Date: Tue, 4 Nov 2025 20:05:31 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E5=A2=9E=E5=8A=A0=E8=BF=90=E5=8A=A8?= =?UTF-8?q?=E5=81=A5=E5=BA=B7=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/budget.ts | 49 ---------- src/apis/exercise.ts | 29 ++++++ src/apis/password.ts | 4 +- src/apis/product.ts | 4 +- src/apis/weight.ts | 29 ++++++ src/components/Health/HealthForm.vue | 100 +++++++++++++++++++ src/components/Health/HealthLegend.vue | 43 ++++++++ src/layout/TabBar.vue | 6 ++ src/store/health.ts | 130 +++++++++++++++++++++++++ src/store/password.ts | 4 +- src/styles/index.module.scss | 2 +- src/types/bill.ts | 4 +- src/types/budget.ts | 42 -------- src/types/food.ts | 70 ++++++------- src/types/health.ts | 30 ++++++ src/types/password.ts | 2 +- src/types/product.ts | 2 +- src/views/health/calendar.vue | 84 ++++++++++++++++ src/views/home/index.vue | 4 + src/views/meta.ts | 14 ++- 20 files changed, 513 insertions(+), 139 deletions(-) delete mode 100644 src/apis/budget.ts create mode 100644 src/apis/exercise.ts create mode 100644 src/apis/weight.ts create mode 100644 src/components/Health/HealthForm.vue create mode 100644 src/components/Health/HealthLegend.vue create mode 100644 src/store/health.ts delete mode 100644 src/types/budget.ts create mode 100644 src/types/health.ts create mode 100644 src/views/health/calendar.vue diff --git a/src/apis/budget.ts b/src/apis/budget.ts deleted file mode 100644 index 800294f..0000000 --- a/src/apis/budget.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { cloudService } from './index' -import { IBudgetInfo } from '@/types/budget' - -export const addBudgetApi = (budget: IBudgetInfo): Promise => - cloudService({ - url: '/home-api/budget', - method: 'post', - data: budget - }) - -export const updateBudgetApi = (id: number, budget: IBudgetInfo): Promise => - cloudService({ - url: `/home-api/budget/${id}`, - method: 'put', - data: budget - }) - -export const deleteBudgetApi = (id: number): Promise => - cloudService({ - url: `/home-api/budget/${id}`, - method: 'DELETE' - }) - -export const queryBudgetApi = (category: string): Promise => - cloudService({ - url: '/home-api/budget', - method: 'get', - params: { category } - }) - -export const queryBudgetCategory = (): Promise => - cloudService({ - url: '/home-api/budget/category', - method: 'get' - }) - -export const queryBudgetRankStats = (category: string): Promise => - cloudService({ - url: '/home-api/budget/stats/rank', - method: 'get', - params: { category } - }) - -export const queryBudgetProjectStats = (category: string): Promise => - cloudService({ - url: '/home-api/budget/stats/project', - method: 'get', - params: { category } - }) diff --git a/src/apis/exercise.ts b/src/apis/exercise.ts new file mode 100644 index 0000000..5e5f10c --- /dev/null +++ b/src/apis/exercise.ts @@ -0,0 +1,29 @@ +import { cloudService } from './index' +import { IExercise } from '@/types/health' + +export const addExerciseApi = (exercise: IExercise): Promise => + cloudService({ + url: '/home-api/exercise', + method: 'post', + data: exercise + }) + +export const updateExerciseApi = (id: number, exercise: IExercise): Promise => + cloudService({ + url: `/home-api/exercise/${id}`, + method: 'put', + data: exercise + }) + +export const deleteExerciseApi = (id: number): Promise => + cloudService({ + url: `/home-api/exercise/${id}`, + method: 'delete' + }) + +export const queryExerciseApi = (query: IExerciseQuery): Promise => + cloudService({ + url: '/home-api/exercise', + method: 'get', + params: query + }) diff --git a/src/apis/password.ts b/src/apis/password.ts index e57df3f..5e7eb23 100644 --- a/src/apis/password.ts +++ b/src/apis/password.ts @@ -1,5 +1,5 @@ import { cloudService } from './index' -import { IPassword, IQueryPassword } from '@/types/password' +import { IPassword, IPasswordQuery } from '@/types/password' export const addPasswordApi = (password: IPassword): Promise => cloudService({ @@ -21,7 +21,7 @@ export const deletePasswordApi = (id: number): Promise => method: 'delete' }) -export const queryPasswordApi = (query: IQueryPassword): Promise => +export const queryPasswordApi = (query: IPasswordQuery): Promise => cloudService({ url: '/home-api/password', method: 'get', diff --git a/src/apis/product.ts b/src/apis/product.ts index 28eccf0..77cd0ea 100644 --- a/src/apis/product.ts +++ b/src/apis/product.ts @@ -1,5 +1,5 @@ import { cloudService } from './index' -import { IProduct, IQueryProduct } from '@/types/product.ts' +import { IProduct, IProductQuery } from '@/types/product.ts' export const addProductApi = (product: IProduct): Promise => cloudService({ @@ -27,7 +27,7 @@ export const queryProductApi = (id: number): Promise => method: 'get' }) -export const queryProductListApi = (query: IQueryProduct): Promise => +export const queryProductListApi = (query: IProductQuery): Promise => cloudService({ url: '/home-api/product', method: 'get', diff --git a/src/apis/weight.ts b/src/apis/weight.ts new file mode 100644 index 0000000..00b7f99 --- /dev/null +++ b/src/apis/weight.ts @@ -0,0 +1,29 @@ +import { cloudService } from './index' +import { IWeight } from '@/types/health' + +export const addWeightApi = (weight: IWeight): Promise => + cloudService({ + url: '/home-api/weight', + method: 'post', + data: weight + }) + +export const updateWeightApi = (id: number, weight: IWeight): Promise => + cloudService({ + url: `/home-api/weight/${id}`, + method: 'put', + data: weight + }) + +export const deleteWeightApi = (id: number): Promise => + cloudService({ + url: `/home-api/weight/${id}`, + method: 'delete' + }) + +export const queryWeightApi = (query: IWeightQuery): Promise => + cloudService({ + url: '/home-api/weight', + method: 'get', + params: query + }) diff --git a/src/components/Health/HealthForm.vue b/src/components/Health/HealthForm.vue new file mode 100644 index 0000000..a92199f --- /dev/null +++ b/src/components/Health/HealthForm.vue @@ -0,0 +1,100 @@ + + + + + diff --git a/src/components/Health/HealthLegend.vue b/src/components/Health/HealthLegend.vue new file mode 100644 index 0000000..fd7a4d0 --- /dev/null +++ b/src/components/Health/HealthLegend.vue @@ -0,0 +1,43 @@ + + + + + diff --git a/src/layout/TabBar.vue b/src/layout/TabBar.vue index 3131d73..61927a9 100644 --- a/src/layout/TabBar.vue +++ b/src/layout/TabBar.vue @@ -43,6 +43,12 @@ 记录 + + + 记录 + + diff --git a/src/store/health.ts b/src/store/health.ts new file mode 100644 index 0000000..ae3e19f --- /dev/null +++ b/src/store/health.ts @@ -0,0 +1,130 @@ +import { defineStore } from 'pinia' +import type { IHandleApi } from 'vue3-common/types' +import { ElMessage } from 'element-plus' +import { + addExerciseApi, + deleteExerciseApi, + queryExerciseApi, + updateExerciseApi +} from '@/apis/exercise' +import { addWeightApi, deleteWeightApi, queryWeightApi, updateWeightApi } from '@/apis/weight' +import { IExercise, IExerciseQuery, IHealth, IWeight } from '@/types/health' + +export const useHealthStore = defineStore('health', { + state: () => ({ + weightRecordList: [] as IWeight[], + exerciseRecordList: [] as IExercise[], + queryInfo: { + startDate: '', + endDate: '' + } as IExerciseQuery, + weightApiType: 'ADD' as IHandleApi, + exerciseApiType: 'ADD' as IHandleApi, + currentExercise: { + project: '', + duration: 0, + date: '' + } as IExercise, + currentHealth: { + project: '', + duration: 0, + value: 0, + date: '' + } as IHealth, + currentWeight: { + value: '', + date: '' + } as IWeight, + selectDate: '', + isScrollEnd: false, + isRefresh: false + }), + actions: { + async queryExerciseRecordList() { + this.exerciseRecordList = await queryExerciseApi(this.queryInfo) + }, + async queryWeightRecordList() { + this.weightRecordList = await queryWeightApi(this.queryInfo) + }, + async handleExerciseApi(exercise: IExercise) { + switch (this.exerciseApiType) { + case 'ADD': + await addExerciseApi(exercise) + ElMessage.success('新增锻炼记录成功') + break + case 'UPDATE': + await updateExerciseApi(exercise.id as number, exercise) + ElMessage.success('更新锻炼记录成功') + break + case 'DELETE': + await deleteExerciseApi(exercise.id as number) + ElMessage.success('删除锻炼记录成功') + break + default: + break + } + await this.refreshInfo() + }, + async handleWeightApi(weight: IWeight) { + switch (this.weightApiType) { + case 'ADD': + await addWeightApi(weight) + ElMessage.success('新增体重记录成功') + break + case 'UPDATE': + await updateWeightApi(weight.id as number, weight) + ElMessage.success('更新体重记录成功') + break + case 'DELETE': + await deleteWeightApi(weight.id as number) + ElMessage.success('删除体重记录成功') + break + default: + break + } + await this.refreshInfo() + }, + getHealthDay(date: string): IHealth { + const exercise = this.exerciseRecordList.find((item) => item.date === date) + const weight = this.weightRecordList.find((item) => item.date === date) + this.currentHealth = this.getEmptyHealth() + + if (exercise) { + this.currentHealth.project = exercise.project + this.currentHealth.duration = exercise.duration + } + + if (weight) { + this.currentHealth.value = weight.value + } + + this.currentHealth.date = date + }, + async refreshInfo() { + await this.queryExerciseRecordList() + await this.queryWeightRecordList() + this.isRefresh = !this.isRefresh + }, + getEmptyExercise(): IExercise { + return { + project: '', + duration: 0, + date: '' + } + }, + getEmptyWeight(): IWeight { + return { + value: 0, + date: '' + } + }, + getEmptyHealth(): IHealth { + return { + date: '', + duration: 0, + project: '', + value: 0 + } + } + } +}) diff --git a/src/store/password.ts b/src/store/password.ts index 2cf210f..5883566 100644 --- a/src/store/password.ts +++ b/src/store/password.ts @@ -1,7 +1,7 @@ import { defineStore } from 'pinia' import type { IHandleApi } from 'vue3-common/types' import { ElMessage } from 'element-plus' -import { IPassword, IQueryPassword } from '@/types/password.ts' +import { IPassword, IPasswordQuery } from '@/types/password.ts' import { addPasswordApi, deletePasswordApi, @@ -15,7 +15,7 @@ export const usePasswordStore = defineStore('password', { queryInfo: { category: '', owner: '哥哥' - } as IQueryPassword, + } as IPasswordQuery, passwordApiType: 'ADD' as IHandleApi, categoryList: [] as string[], currentPassword: { diff --git a/src/styles/index.module.scss b/src/styles/index.module.scss index 866b589..1a65208 100644 --- a/src/styles/index.module.scss +++ b/src/styles/index.module.scss @@ -82,4 +82,4 @@ span, input { font-style: normal; } -@import "//at.alicdn.com/t/c/font_4793264_6bh098pu52x.css"; +@import "//at.alicdn.com/t/c/font_4793264_jis1w9io0s8.css"; diff --git a/src/types/bill.ts b/src/types/bill.ts index 42309f6..183c950 100644 --- a/src/types/bill.ts +++ b/src/types/bill.ts @@ -1,3 +1,5 @@ +export type IBillType = 'expensive' | 'income' | '' + /** * 账单记录 */ @@ -70,5 +72,3 @@ export interface IBillSummaryStats { balance: number; rate: number; } - -export type IBillType = 'expensive' | 'income' | '' diff --git a/src/types/budget.ts b/src/types/budget.ts deleted file mode 100644 index fc40d6b..0000000 --- a/src/types/budget.ts +++ /dev/null @@ -1,42 +0,0 @@ -/** - * 预算信息 - */ -export interface IBudgetInfo { - id?: number; - /** - * 预算类别 - */ - category: string; - /** - * 预算项目 - */ - project: string; - /** - * 预算内容 - */ - content: string; - /** - * 预算供应商 - */ - vendor: string; - /** - * 预算支出 - */ - budget: number; - /** - * 实际支出 - */ - actual: number; - /** - * 支付时间 - */ - payTime: string; - /** - * 备注 - */ - remake: string; -} - -export interface IBudgetQuery { - category: string; -} diff --git a/src/types/food.ts b/src/types/food.ts index a49c224..d777ffd 100644 --- a/src/types/food.ts +++ b/src/types/food.ts @@ -1,38 +1,3 @@ -/** - * 菜谱信息 - */ -export interface IFoodRecipe { - id?: number; - /** - * 美食名称 - */ - name: string; - /** - * 美食菜系 - */ - category: string; - /** - * 推荐指数 - */ - recommendRate: number; - /** - * 备注 - */ - remark: string; - /** - * 食材 - */ - materialList: IFoodMaterial[]; - /** - * 步骤 - */ - stepList: IFoodStep[]; - /** - * 成果 - */ - recordList: IFoodRecord[]; -} - /** * 食材信息 */ @@ -72,6 +37,41 @@ export interface IFoodStats { workCount: number; } +/** + * 菜谱信息 + */ +export interface IFoodRecipe { + id?: number; + /** + * 美食名称 + */ + name: string; + /** + * 美食菜系 + */ + category: string; + /** + * 推荐指数 + */ + recommendRate: number; + /** + * 备注 + */ + remark: string; + /** + * 食材 + */ + materialList: IFoodMaterial[]; + /** + * 步骤 + */ + stepList: IFoodStep[]; + /** + * 成果 + */ + recordList: IFoodRecord[]; +} + export interface IFoodQuery { category: string; } diff --git a/src/types/health.ts b/src/types/health.ts new file mode 100644 index 0000000..1c4429f --- /dev/null +++ b/src/types/health.ts @@ -0,0 +1,30 @@ +export interface IHealth { + id?: number; + sportProject: string; + sportDuration: number; + weight: number; + date: string; +} + +export interface IExercise { + id?: number; + project: string; + duration: number; + date: string; +} + +export interface IHealthQuery { + startDate: string; + endDate: string; +} + +export interface IWeight { + id?: number; + value: number; + date: string; +} + +export interface IWeightQuery { + startDate: string; + endDate: string; +} diff --git a/src/types/password.ts b/src/types/password.ts index 64569b8..b18905d 100644 --- a/src/types/password.ts +++ b/src/types/password.ts @@ -30,7 +30,7 @@ export interface IPassword { remark: string; } -export interface IQueryPassword { +export interface IPasswordQuery { category: string; owner: string; } diff --git a/src/types/product.ts b/src/types/product.ts index 6a77380..0e3e703 100644 --- a/src/types/product.ts +++ b/src/types/product.ts @@ -42,7 +42,7 @@ export interface IProduct { imageUrl: string; } -export interface IQueryProduct { +export interface IProductQuery { category: string; order: string; } diff --git a/src/views/health/calendar.vue b/src/views/health/calendar.vue new file mode 100644 index 0000000..cdbd3c1 --- /dev/null +++ b/src/views/health/calendar.vue @@ -0,0 +1,84 @@ + + + + + diff --git a/src/views/home/index.vue b/src/views/home/index.vue index d3a042f..9e2e171 100644 --- a/src/views/home/index.vue +++ b/src/views/home/index.vue @@ -36,6 +36,10 @@ title="物品记录" sub-title="收纳生活琐碎" router="/product/list"/> + + diff --git a/src/views/meta.ts b/src/views/meta.ts index 1272f3c..4070842 100644 --- a/src/views/meta.ts +++ b/src/views/meta.ts @@ -29,7 +29,7 @@ export const mobileHomeMeta: IRouteMetaConfig = { }, '/bill': { title: '收支记录', - icon: 'home-bill', + icon: '', order: 2, redirect: '/bill/data' }, @@ -51,7 +51,7 @@ export const mobileHomeMeta: IRouteMetaConfig = { }, '/travel': { title: '旅行记录', - icon: 'home-food', + icon: '', order: 4, redirect: '/travel/spot' }, @@ -75,6 +75,16 @@ export const mobileHomeMeta: IRouteMetaConfig = { title: '记录表单', icon: '' }, + '/health': { + title: '运动健康', + icon: '', + order: 4, + redirect: '/health/calendar' + }, + '/health/calendar': { + title: '记录', + icon: '' + }, '/plan': { title: '时光日程', icon: 'home-calendar',