feat:增加月经天数统计

This commit is contained in:
2025-10-30 15:00:50 +08:00
parent 930202a6b6
commit cc33d3028b
7 changed files with 133 additions and 3 deletions

View File

@@ -1,5 +1,5 @@
import { cloudService } from './index'
import { IPeriodDay, IPeriodSetting } from '@/types/period.ts'
import { IMenstrualPeriod, IPeriodDay, IPeriodSetting } from '@/types/period.ts'
export const updatePeriodDayApi = (id: number, periodDay: IPeriodDay): Promise<boolean> =>
@@ -16,6 +16,12 @@ export const queryPeriodDayApi = (month: string): Promise<IPeriodDay[]> =>
params: { month }
})
export const getMenstrualDaysApi = (): Promise<IMenstrualPeriod[]> =>
cloudService({
url: '/home-api/period//menstruate/days',
method: 'get'
})
export const getMenstruateFirstDateApi = (month: string): Promise<string> =>
cloudService({
url: '/home-api/period/menstruate',

View File

@@ -70,6 +70,11 @@
<i class="fa-solid fa-calendar-days"></i>
<span>记录</span>
</router-link>
<router-link v-if="path.includes('period')" to="/period/status"
@click="routerClick()" class="item">
<i class="fa-solid fa-chart-pie"></i>
<span>统计</span>
</router-link>
<router-link v-if="path.includes('period')" to="/period/setting"
@click="routerClick()" class="item">
<i class="fa-solid fa-gear"></i>

View File

@@ -1,7 +1,8 @@
import { defineStore } from 'pinia'
import { IHandleApi } from 'vue3-common/types'
import { IPeriodDay, IPeriodSetting } from '@/types/period.ts'
import { IMenstrualPeriod, IPeriodDay, IPeriodSetting } from '@/types/period.ts'
import {
getMenstrualDaysApi,
getMenstruateFirstDateApi,
queryPeriodDayApi,
queryPeriodSettingApi,
@@ -13,6 +14,7 @@ import { getCurrentMonth } from 'vue3-common/utils/dateUtil'
export const usePeriodStore = defineStore('period', {
state: () => ({
periodDayList: [] as IPeriodDay[],
menstrualDaysList: [] as IMenstrualPeriod[],
periodSetting: {
id: 0,
cycleLength: 0,
@@ -52,6 +54,9 @@ export const usePeriodStore = defineStore('period', {
async getMenstruateFirstDate(month: string) {
this.menstruateFirstDate = await getMenstruateFirstDateApi(month)
},
async getMenstruateDays() {
this.menstrualDaysList = await getMenstrualDaysApi()
},
async refreshInfo() {
await this.queryPeriodDayList()
await this.queryPeriodSetting()

View File

@@ -35,3 +35,8 @@ export interface IPeriodSetting {
duration: number;
isCalculate: boolean;
}
export interface IMenstrualPeriod{
startDate: string;
endDate: string;
}

View File

@@ -143,6 +143,10 @@ export const mobileHomeMeta: IRouteMetaConfig = {
title: '记录',
icon: ''
},
'/period/status': {
title: '统计',
icon: ''
},
'/period/setting': {
title: '设置',
icon: ''

105
src/views/period/status.vue Normal file
View File

@@ -0,0 +1,105 @@
<template>
<div class="mobile-period-chart common-mobile-view">
<el-tabs v-model="activeName" type="card">
<el-tab-pane label="月经周期" name="menstrualDays">
<div v-if="periodStore.menstrualDaysList.length > 0" class="content">
<div v-for="(item, index) in periodStore.menstrualDaysList"
:key="index" class="period-item"
:style="{ background: getPeriod(item) > duration ? '#fee2e2' : '#FFFFFF'}"
>
<span>开始日期: {{ item.startDate }}</span>
<span>结束日期: {{ item.endDate }}</span>
<span>天数: {{ getPeriod(item) }}</span>
<span v-if="getPeriod(item) > duration" class="warning-menstrual">周期过长</span>
</div>
</div>
<div v-else class="empty-state">
<el-empty description="暂无记录"></el-empty>
</div>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script lang="ts" setup>
import { computed, onMounted, ref } from 'vue'
import { getDateDifference } from 'vue3-common/utils/dateUtil'
import { usePeriodStore } from '@/store/period'
import { IMenstrualPeriod } from '@/types/period'
const periodStore = usePeriodStore()
const duration = computed(() => periodStore.periodSetting.duration)
const activeName = ref('menstrualDays')
onMounted(() => {
periodStore.getMenstruateDays()
})
const getPeriod = (item: IMenstrualPeriod) => {
return getDateDifference(item.startDate, item.endDate, 'days')
}
</script>
<style scoped lang="scss">
.mobile-period-chart {
.content {
display: flex;
flex-direction: column;
gap: 10px;
.period-item {
position: relative;
background: white;
border-radius: 10px;
padding: 20px;
display: flex;
flex-direction: column;
gap: 10px;
span {
display: flex;
align-items: center;
&::before {
content: "";
display: inline-block;
width: 6px;
height: 6px;
border-radius: 50%;
margin-right: 10px;
}
&:nth-child(1)::before {
background: #ec4899;
}
&:nth-child(2)::before {
background: #f59e0b;
}
&:nth-child(3)::before {
background: #10b981;
}
}
.warning-menstrual {
position: absolute;
top: 10px;
right: 10px;
background: #dc2626;
color: white;
padding: 5px;
border-radius: 10px;
&::before {
content: none;
}
}
}
}
}
</style>