feat:增加月经日期统计

This commit is contained in:
2025-10-30 15:00:00 +08:00
parent 67c72779ad
commit c8d2bd1df0
20 changed files with 213 additions and 104 deletions

View File

@@ -2,6 +2,7 @@ package com.cxx.home.controller;
import com.cxx.common.ReadView;
import com.cxx.common.WriteView;
import com.cxx.home.dto.period.MenstrualPeriodDto;
import com.cxx.home.dto.period.PeriodDayDto;
import com.cxx.home.dto.period.PeriodSettingDto;
import com.cxx.home.service.PeriodService;
@@ -39,6 +40,12 @@ public class PeriodController {
return periodService.getMenstruateFirstDate(month);
}
@Operation(summary = "获取月经周期天数")
@GetMapping("/menstruate/days")
public List<MenstrualPeriodDto> getMenstrualPeriod() {
return periodService.getMenstrualPeriod();
}
@Operation(summary = "查询月经设置")
@GetMapping("/setting")
public @JsonView(ReadView.class) PeriodSettingDto queryPeriodSetting() {

View File

@@ -0,0 +1,18 @@
package com.cxx.home.converter;
import com.cxx.home.dto.journal.JournalDto;
import com.cxx.home.entity.Journal;
import org.mapstruct.Mapper;
import java.util.List;
@Mapper(componentModel = "spring")
public interface JournalConverter {
Journal toEntity(JournalDto dto);
List<Journal> toEntities(List<JournalDto> dto);
JournalDto toDto(Journal entities);
List<JournalDto> toDtos(List<Journal> entities);
}

View File

@@ -0,0 +1,18 @@
package com.cxx.home.converter;
import com.cxx.home.dto.kpi.KpiDto;
import com.cxx.home.entity.Kpi;
import org.mapstruct.Mapper;
import java.util.List;
@Mapper(componentModel = "spring")
public interface KpiConverter {
Kpi toEntity(KpiDto dto);
List<Kpi> toEntities(List<KpiDto> dto);
KpiDto toDto(Kpi entities);
List<KpiDto> toDtos(List<Kpi> entities);
}

View File

@@ -0,0 +1,18 @@
package com.cxx.home.converter;
import com.cxx.home.dto.product.ProductDto;
import com.cxx.home.entity.Product;
import org.mapstruct.Mapper;
import java.util.List;
@Mapper(componentModel = "spring")
public interface ProductConverter {
Product toEntity(ProductDto dto);
List<Product> toEntities(List<ProductDto> dto);
ProductDto toDto(Product entities);
List<ProductDto> toDtos(List<Product> entities);
}

View File

@@ -1,13 +0,0 @@
package com.cxx.home.dao;
import com.cxx.home.dto.kpi.KpiDto;
import com.cxx.home.vo.KpiQueryVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface KpiDao {
List<KpiDto> queryKpi(@Param("query") KpiQueryVo queryVo);
}

View File

@@ -9,9 +9,5 @@ import java.util.List;
@Mapper
public interface ProductDao {
ProductDto queryProduct(@Param("id") Long id);
List<ProductDto> queryProductList(@Param("query") ProductQueryVo queryVo);
List<String> queryProductCategory();
}

View File

@@ -0,0 +1,13 @@
package com.cxx.home.dto.period;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.time.LocalDate;
@Data
@AllArgsConstructor
public class MenstrualPeriodDto {
private LocalDate startDate;
private LocalDate endDate;
}

View File

@@ -8,7 +8,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
import java.time.LocalDate;
@Getter
@Setter
@@ -20,7 +20,7 @@ public class PeriodDayDto {
@Schema(description = "日期")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date date;
private LocalDate date;
@Schema(description = "是否吃药")
private Boolean isDrug;

View File

@@ -6,14 +6,14 @@ import com.cxx.framework.data.AbstractEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
import java.time.LocalDate;
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("period_day")
public class PeriodDay extends AbstractEntity {
@TableField("date")
private Date date;
private LocalDate date;
@TableField("is_drug")
private Integer isDrug;

View File

@@ -1,5 +1,6 @@
package com.cxx.home.service;
import com.cxx.home.dto.period.MenstrualPeriodDto;
import com.cxx.home.dto.period.PeriodDayDto;
import com.cxx.home.dto.period.PeriodSettingDto;
@@ -15,4 +16,6 @@ public interface PeriodService {
Boolean updatePeriodSetting(Long id, PeriodSettingDto periodSettingDto);
PeriodSettingDto queryPeriodSetting();
List<MenstrualPeriodDto> getMenstrualPeriod();
}

View File

@@ -184,7 +184,7 @@ public class FoodServiceImpl implements FoodService {
@Override
public List<String> queryFoodName() {
return foodRecipeMapper.selectList(null)
return foodRecipeMapper.selectList(Wrappers.emptyWrapper())
.stream().map(FoodRecipe::getName).collect(Collectors.toList());
}

View File

@@ -1,6 +1,8 @@
package com.cxx.home.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cxx.framework.web.CustomException;
import com.cxx.home.converter.JournalConverter;
import com.cxx.home.dao.JournalDao;
import com.cxx.home.dto.journal.JournalDto;
import com.cxx.home.entity.Journal;
@@ -11,6 +13,7 @@ import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.util.List;
@Service
@@ -21,6 +24,9 @@ public class JournalServiceImpl implements JournalService {
@Resource
private JournalMapper journalMapper;
@Resource
private JournalConverter journalConverter;
@Override
public Boolean addJournal(JournalDto journalDto) {
Journal journal = new Journal();
@@ -52,6 +58,14 @@ public class JournalServiceImpl implements JournalService {
@Override
public List<JournalDto> queryJournal(JournalQueryVo queryVo) {
return journalDao.queryJournal(queryVo);
LocalDate startDate = LocalDate.parse(queryVo.getStartDate());
LocalDate endDate = LocalDate.parse(queryVo.getEndDate());
LambdaQueryWrapper<Journal> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.ge(Journal::getDate, startDate)
.le(Journal::getDate, endDate)
.orderByDesc(Journal::getDate);
return journalConverter.toDtos(journalMapper.selectList(queryWrapper));
}
}

View File

@@ -1,7 +1,8 @@
package com.cxx.home.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cxx.framework.web.CustomException;
import com.cxx.home.dao.KpiDao;
import com.cxx.home.converter.KpiConverter;
import com.cxx.home.dto.kpi.KpiDto;
import com.cxx.home.entity.Kpi;
import com.cxx.home.mapper.KpiMapper;
@@ -11,16 +12,16 @@ import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import java.time.LocalDate;
import java.util.List;
@Service
public class KpiServiceImpl implements KpiService {
@Resource
private KpiDao kpiDao;
@Resource
private KpiMapper kpiMapper;
@Resource
private KpiConverter kpiConverter;
@Override
public Boolean addKpi(KpiDto kpiDto) {
@@ -53,6 +54,14 @@ public class KpiServiceImpl implements KpiService {
@Override
public List<KpiDto> queryKpi(KpiQueryVo queryVo) {
return kpiDao.queryKpi(queryVo);
LocalDate startDate = LocalDate.parse(queryVo.getStartDate());
LocalDate endDate = LocalDate.parse(queryVo.getEndDate());
LambdaQueryWrapper<Kpi> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.ge(Kpi::getDate, startDate)
.le(Kpi::getDate, endDate)
.orderByDesc(Kpi::getDate);
return kpiConverter.toDtos(kpiMapper.selectList(queryWrapper));
}
}

View File

@@ -1,12 +1,13 @@
package com.cxx.home.service.impl;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cxx.framework.web.CustomException;
import com.cxx.home.dao.PasswordDao;
import com.cxx.home.dto.password.PasswordDto;
import com.cxx.home.entity.Password;
import com.cxx.home.mapper.PasswordMapper;
import com.cxx.home.service.PasswordService;
import com.cxx.home.util.CommonUtils;
import com.cxx.home.vo.PasswordQueryVo;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
@@ -14,6 +15,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class PasswordServiceImpl implements PasswordService {
@@ -30,7 +32,7 @@ public class PasswordServiceImpl implements PasswordService {
public Boolean add(PasswordDto passwordDto) {
Password password = new Password();
BeanUtils.copyProperties(passwordDto, password);
password.setPassword(encryptPassword(passwordDto.getPassword()));
password.setPassword(CommonUtils.encryptPassword(secretKey, passwordDto.getPassword()));
return passwordMapper.insert(password) == 1;
}
@@ -44,7 +46,7 @@ public class PasswordServiceImpl implements PasswordService {
Password password = new Password();
BeanUtils.copyProperties(passwordDto, password);
password.setId(id);
password.setPassword(encryptPassword(passwordDto.getPassword()));
password.setPassword(CommonUtils.encryptPassword(secretKey, passwordDto.getPassword()));
return passwordMapper.updateById(password) == 1;
}
@@ -61,20 +63,15 @@ public class PasswordServiceImpl implements PasswordService {
public List<PasswordDto> query(PasswordQueryVo query) {
List<PasswordDto> passwordList = passwordDao.query(query);
passwordList.forEach(item -> item.setPassword(decryptStr(item.getPassword())));
passwordList.forEach(item -> item.setPassword(CommonUtils.decryptStr(secretKey, item.getPassword())));
return passwordList;
}
@Override
public List<String > queryCategory() {
return passwordDao.queryCategory();
}
public List<String> queryCategory() {
LambdaQueryWrapper<Password> queryWrapper = new LambdaQueryWrapper<>();
List<Object> categories = passwordMapper.selectObjs(queryWrapper.select(Password::getCategory));
private String encryptPassword(String password) {
return SecureUtil.aes(secretKey.getBytes()).encryptBase64(password);
}
private String decryptStr(String password) {
return SecureUtil.aes(secretKey.getBytes()).decryptStr(password);
return categories.stream().map(Object::toString).distinct().collect(Collectors.toList());
}
}

View File

@@ -1,6 +1,8 @@
package com.cxx.home.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cxx.home.dao.PeriodDao;
import com.cxx.home.dto.period.MenstrualPeriodDto;
import com.cxx.home.dto.period.PeriodDayDto;
import com.cxx.home.dto.period.PeriodSettingDto;
import com.cxx.home.entity.PeriodDay;
@@ -13,6 +15,9 @@ import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@Service
@@ -89,16 +94,55 @@ public class PeriodServiceImpl implements PeriodService {
List<PeriodSetting> periodSettingList = periodSettingMapper.selectList(null);
PeriodSettingDto periodSettingDto = new PeriodSettingDto();
if (periodSettingList.size() > 0) {
BeanUtils.copyProperties(periodSettingList.get(0), periodSettingDto);
periodSettingDto.setIsCalculate(periodSettingList.get(0).getIsCalculate() == 1);
} else {
if (periodSettingList.isEmpty()) {
periodSettingDto.setId(0L);
periodSettingDto.setCycleLength(0);
periodSettingDto.setDuration(0);
periodSettingDto.setIsCalculate(false);
} else {
BeanUtils.copyProperties(periodSettingList.get(0), periodSettingDto);
periodSettingDto.setIsCalculate(periodSettingList.get(0).getIsCalculate() == 1);
}
return periodSettingDto;
}
@Override
public List<MenstrualPeriodDto> getMenstrualPeriod() {
LambdaQueryWrapper<PeriodDay> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(PeriodDay::getIsMenstruate, 1).select(PeriodDay::getDate).orderByAsc(PeriodDay::getDate);
List<LocalDate> dates = periodDayMapper.selectList(queryWrapper)
.stream().map(PeriodDay::getDate).toList();
if (dates.isEmpty()) {
return Collections.emptyList();
}
List<MenstrualPeriodDto> result = new ArrayList<>();
LocalDate start = dates.get(0);
LocalDate end = dates.get(0);
for (int i = 1; i < dates.size(); i++) {
LocalDate current = dates.get(i);
// 如果当前日期与前一天连续,继续当前周期
if (current.equals(end.plusDays(1))) {
end = current;
} else {
// 日期不连续,保存当前周期,开始新周期
result.add(new MenstrualPeriodDto(start, end));
// 重新开始新的周期
start = current;
end = current;
}
}
// 添加最后一个周期
result.add(new MenstrualPeriodDto(start, end));
Collections.reverse(result);
return result;
}
}

View File

@@ -2,6 +2,7 @@ package com.cxx.home.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cxx.framework.web.CustomException;
import com.cxx.home.converter.ProductConverter;
import com.cxx.home.dao.ProductDao;
import com.cxx.home.dto.product.ProductDto;
import com.cxx.home.entity.*;
@@ -14,6 +15,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class ProductServiceImpl implements ProductService {
@@ -23,6 +25,9 @@ public class ProductServiceImpl implements ProductService {
@Resource
private ProductMapper productMapper;
@Resource
private ProductConverter productConverter;
@Override
@Transactional
public Boolean addProduct(ProductDto productDto) {
@@ -61,7 +66,7 @@ public class ProductServiceImpl implements ProductService {
throw new CustomException("该商品不存在");
}
return productDao.queryProduct(id);
return productConverter.toDto(productMapper.selectById(id));
}
@Override
@@ -71,6 +76,9 @@ public class ProductServiceImpl implements ProductService {
@Override
public List<String> queryProductCategory() {
return productDao.queryProductCategory();
LambdaQueryWrapper<Product> queryWrapper = new LambdaQueryWrapper<>();
List<Object> categories = productMapper.selectObjs(queryWrapper.select(Product::getCategory));
return categories.stream().map(Object::toString).distinct().collect(Collectors.toList());
}
}

View File

@@ -0,0 +1,13 @@
package com.cxx.home.util;
import cn.hutool.crypto.SecureUtil;
public class CommonUtils {
public static String encryptPassword(String secretKey, String password) {
return SecureUtil.aes(secretKey.getBytes()).encryptBase64(password);
}
public static String decryptStr(String secretKey, String password) {
return SecureUtil.aes(secretKey.getBytes()).decryptStr(password);
}
}