Преглед на файлове

feat(service): 添加健康数据服务接口与实现

- 新增血糖、血压、心率和体征数据的服务接口
- 实现各类健康数据的分页查询功能
- 支持基于时间范围的数据筛选
- 添加 BMI 计算方法用于体征数据处理
- 集成基础查询请求对象统一处理分页和时间参数
mcbaiyun преди 2 месеца
родител
ревизия
1f85691183

+ 25 - 0
src/main/java/work/baiyun/chronicdiseaseapp/model/vo/BaseQueryRequest.java

@@ -0,0 +1,25 @@
+package work.baiyun.chronicdiseaseapp.model.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import jakarta.validation.constraints.*;
+import java.time.LocalDateTime;
+
+@Schema(description = "基础查询请求")
+@Data
+public class BaseQueryRequest {
+    @Schema(description = "页码", minimum = "1", defaultValue = "1")
+    @Min(1)
+    private Integer pageNum = 1;
+
+    @Schema(description = "每页大小", minimum = "1", maximum = "100", defaultValue = "10")
+    @Min(1) @Max(100)
+    private Integer pageSize = 10;
+
+    @Schema(description = "开始时间")
+    private LocalDateTime startTime;
+
+    @Schema(description = "结束时间")
+    private LocalDateTime endTime;
+}

+ 11 - 0
src/main/java/work/baiyun/chronicdiseaseapp/service/BloodGlucoseDataService.java

@@ -0,0 +1,11 @@
+package work.baiyun.chronicdiseaseapp.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import work.baiyun.chronicdiseaseapp.model.vo.BaseQueryRequest;
+import work.baiyun.chronicdiseaseapp.model.vo.BloodGlucoseDataResponse;
+import work.baiyun.chronicdiseaseapp.model.vo.AddBloodGlucoseDataRequest;
+
+public interface BloodGlucoseDataService {
+    void addBloodGlucoseData(AddBloodGlucoseDataRequest request);
+    Page<BloodGlucoseDataResponse> listBloodGlucoseData(BaseQueryRequest request);
+}

+ 11 - 0
src/main/java/work/baiyun/chronicdiseaseapp/service/BloodPressureDataService.java

@@ -0,0 +1,11 @@
+package work.baiyun.chronicdiseaseapp.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import work.baiyun.chronicdiseaseapp.model.vo.BaseQueryRequest;
+import work.baiyun.chronicdiseaseapp.model.vo.BloodPressureDataResponse;
+import work.baiyun.chronicdiseaseapp.model.vo.AddBloodPressureDataRequest;
+
+public interface BloodPressureDataService {
+    void addBloodPressureData(AddBloodPressureDataRequest request);
+    Page<BloodPressureDataResponse> listBloodPressureData(BaseQueryRequest request);
+}

+ 11 - 0
src/main/java/work/baiyun/chronicdiseaseapp/service/HeartRateDataService.java

@@ -0,0 +1,11 @@
+package work.baiyun.chronicdiseaseapp.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import work.baiyun.chronicdiseaseapp.model.vo.BaseQueryRequest;
+import work.baiyun.chronicdiseaseapp.model.vo.HeartRateDataResponse;
+import work.baiyun.chronicdiseaseapp.model.vo.AddHeartRateDataRequest;
+
+public interface HeartRateDataService {
+    void addHeartRateData(AddHeartRateDataRequest request);
+    Page<HeartRateDataResponse> listHeartRateData(BaseQueryRequest request);
+}

+ 14 - 0
src/main/java/work/baiyun/chronicdiseaseapp/service/PhysicalDataService.java

@@ -0,0 +1,14 @@
+package work.baiyun.chronicdiseaseapp.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import work.baiyun.chronicdiseaseapp.model.vo.BaseQueryRequest;
+import work.baiyun.chronicdiseaseapp.model.vo.PhysicalDataResponse;
+import work.baiyun.chronicdiseaseapp.model.vo.AddPhysicalDataRequest;
+
+import java.math.BigDecimal;
+
+public interface PhysicalDataService {
+    void addPhysicalData(AddPhysicalDataRequest request);
+    Page<PhysicalDataResponse> listPhysicalData(BaseQueryRequest request);
+    BigDecimal calculateBMI(BigDecimal height, BigDecimal weight);
+}

+ 63 - 0
src/main/java/work/baiyun/chronicdiseaseapp/service/impl/BloodGlucoseDataServiceImpl.java

@@ -0,0 +1,63 @@
+package work.baiyun.chronicdiseaseapp.service.impl;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import work.baiyun.chronicdiseaseapp.mapper.BloodGlucoseDataMapper;
+import work.baiyun.chronicdiseaseapp.model.po.BloodGlucoseData;
+import work.baiyun.chronicdiseaseapp.model.vo.BaseQueryRequest;
+import work.baiyun.chronicdiseaseapp.model.vo.BloodGlucoseDataResponse;
+import work.baiyun.chronicdiseaseapp.model.vo.AddBloodGlucoseDataRequest;
+import work.baiyun.chronicdiseaseapp.service.BloodGlucoseDataService;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Service
+public class BloodGlucoseDataServiceImpl implements BloodGlucoseDataService {
+
+    @Autowired
+    private BloodGlucoseDataMapper bloodGlucoseDataMapper;
+
+    @Override
+    public void addBloodGlucoseData(AddBloodGlucoseDataRequest request) {
+        Long userId = getCurrentUserId();
+        BloodGlucoseData record = new BloodGlucoseData();
+        BeanUtils.copyProperties(request, record);
+        record.setUserId(userId);
+        bloodGlucoseDataMapper.insert(record);
+    }
+
+    @Override
+    public Page<BloodGlucoseDataResponse> listBloodGlucoseData(BaseQueryRequest request) {
+        Long userId = getCurrentUserId();
+        Page<BloodGlucoseData> page = new Page<>(request.getPageNum(), request.getPageSize());
+        LambdaQueryWrapper<BloodGlucoseData> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(BloodGlucoseData::getUserId, userId)
+               .ge(request.getStartTime() != null, BloodGlucoseData::getMeasureTime, request.getStartTime())
+               .le(request.getEndTime() != null, BloodGlucoseData::getMeasureTime, request.getEndTime())
+               .orderByDesc(BloodGlucoseData::getMeasureTime);
+
+        Page<BloodGlucoseData> result = bloodGlucoseDataMapper.selectPage(page, wrapper);
+
+        List<BloodGlucoseDataResponse> responses = result.getRecords().stream().map(r -> {
+            BloodGlucoseDataResponse resp = new BloodGlucoseDataResponse();
+            BeanUtils.copyProperties(r, resp);
+            return resp;
+        }).collect(Collectors.toList());
+
+        Page<BloodGlucoseDataResponse> responsePage = new Page<>();
+        responsePage.setRecords(responses);
+        responsePage.setCurrent(result.getCurrent());
+        responsePage.setSize(result.getSize());
+        responsePage.setTotal(result.getTotal());
+        return responsePage;
+    }
+
+    private Long getCurrentUserId() {
+        // TODO: replace with actual security context lookup
+        return 1L;
+    }
+}

+ 63 - 0
src/main/java/work/baiyun/chronicdiseaseapp/service/impl/BloodPressureDataServiceImpl.java

@@ -0,0 +1,63 @@
+package work.baiyun.chronicdiseaseapp.service.impl;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import work.baiyun.chronicdiseaseapp.mapper.BloodPressureDataMapper;
+import work.baiyun.chronicdiseaseapp.model.po.BloodPressureData;
+import work.baiyun.chronicdiseaseapp.model.vo.BaseQueryRequest;
+import work.baiyun.chronicdiseaseapp.model.vo.BloodPressureDataResponse;
+import work.baiyun.chronicdiseaseapp.model.vo.AddBloodPressureDataRequest;
+import work.baiyun.chronicdiseaseapp.service.BloodPressureDataService;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Service
+public class BloodPressureDataServiceImpl implements BloodPressureDataService {
+
+    @Autowired
+    private BloodPressureDataMapper bloodPressureDataMapper;
+
+    @Override
+    public void addBloodPressureData(AddBloodPressureDataRequest request) {
+        Long userId = getCurrentUserId();
+        BloodPressureData record = new BloodPressureData();
+        BeanUtils.copyProperties(request, record);
+        record.setUserId(userId);
+        bloodPressureDataMapper.insert(record);
+    }
+
+    @Override
+    public Page<BloodPressureDataResponse> listBloodPressureData(BaseQueryRequest request) {
+        Long userId = getCurrentUserId();
+        Page<BloodPressureData> page = new Page<>(request.getPageNum(), request.getPageSize());
+        LambdaQueryWrapper<BloodPressureData> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(BloodPressureData::getUserId, userId)
+               .ge(request.getStartTime() != null, BloodPressureData::getMeasureTime, request.getStartTime())
+               .le(request.getEndTime() != null, BloodPressureData::getMeasureTime, request.getEndTime())
+               .orderByDesc(BloodPressureData::getMeasureTime);
+
+        Page<BloodPressureData> result = bloodPressureDataMapper.selectPage(page, wrapper);
+
+        List<BloodPressureDataResponse> responses = result.getRecords().stream().map(r -> {
+            BloodPressureDataResponse resp = new BloodPressureDataResponse();
+            BeanUtils.copyProperties(r, resp);
+            return resp;
+        }).collect(Collectors.toList());
+
+        Page<BloodPressureDataResponse> responsePage = new Page<>();
+        responsePage.setRecords(responses);
+        responsePage.setCurrent(result.getCurrent());
+        responsePage.setSize(result.getSize());
+        responsePage.setTotal(result.getTotal());
+        return responsePage;
+    }
+
+    private Long getCurrentUserId() {
+        // TODO: replace with actual security context lookup
+        return 1L;
+    }
+}

+ 63 - 0
src/main/java/work/baiyun/chronicdiseaseapp/service/impl/HeartRateDataServiceImpl.java

@@ -0,0 +1,63 @@
+package work.baiyun.chronicdiseaseapp.service.impl;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import work.baiyun.chronicdiseaseapp.mapper.HeartRateDataMapper;
+import work.baiyun.chronicdiseaseapp.model.po.HeartRateData;
+import work.baiyun.chronicdiseaseapp.model.vo.BaseQueryRequest;
+import work.baiyun.chronicdiseaseapp.model.vo.HeartRateDataResponse;
+import work.baiyun.chronicdiseaseapp.model.vo.AddHeartRateDataRequest;
+import work.baiyun.chronicdiseaseapp.service.HeartRateDataService;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Service
+public class HeartRateDataServiceImpl implements HeartRateDataService {
+
+    @Autowired
+    private HeartRateDataMapper heartRateDataMapper;
+
+    @Override
+    public void addHeartRateData(AddHeartRateDataRequest request) {
+        Long userId = getCurrentUserId();
+        HeartRateData record = new HeartRateData();
+        BeanUtils.copyProperties(request, record);
+        record.setUserId(userId);
+        heartRateDataMapper.insert(record);
+    }
+
+    @Override
+    public Page<HeartRateDataResponse> listHeartRateData(BaseQueryRequest request) {
+        Long userId = getCurrentUserId();
+        Page<HeartRateData> page = new Page<>(request.getPageNum(), request.getPageSize());
+        LambdaQueryWrapper<HeartRateData> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(HeartRateData::getUserId, userId)
+               .ge(request.getStartTime() != null, HeartRateData::getMeasureTime, request.getStartTime())
+               .le(request.getEndTime() != null, HeartRateData::getMeasureTime, request.getEndTime())
+               .orderByDesc(HeartRateData::getMeasureTime);
+
+        Page<HeartRateData> result = heartRateDataMapper.selectPage(page, wrapper);
+
+        List<HeartRateDataResponse> responses = result.getRecords().stream().map(r -> {
+            HeartRateDataResponse resp = new HeartRateDataResponse();
+            BeanUtils.copyProperties(r, resp);
+            return resp;
+        }).collect(Collectors.toList());
+
+        Page<HeartRateDataResponse> responsePage = new Page<>();
+        responsePage.setRecords(responses);
+        responsePage.setCurrent(result.getCurrent());
+        responsePage.setSize(result.getSize());
+        responsePage.setTotal(result.getTotal());
+        return responsePage;
+    }
+
+    private Long getCurrentUserId() {
+        // TODO: replace with actual security context lookup
+        return 1L;
+    }
+}

+ 77 - 0
src/main/java/work/baiyun/chronicdiseaseapp/service/impl/PhysicalDataServiceImpl.java

@@ -0,0 +1,77 @@
+package work.baiyun.chronicdiseaseapp.service.impl;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import work.baiyun.chronicdiseaseapp.mapper.PhysicalDataMapper;
+import work.baiyun.chronicdiseaseapp.model.po.PhysicalData;
+import work.baiyun.chronicdiseaseapp.model.vo.BaseQueryRequest;
+import work.baiyun.chronicdiseaseapp.model.vo.PhysicalDataResponse;
+import work.baiyun.chronicdiseaseapp.model.vo.AddPhysicalDataRequest;
+import work.baiyun.chronicdiseaseapp.service.PhysicalDataService;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Service
+public class PhysicalDataServiceImpl implements PhysicalDataService {
+
+    @Autowired
+    private PhysicalDataMapper physicalDataMapper;
+
+    @Override
+    public void addPhysicalData(AddPhysicalDataRequest request) {
+        Long userId = getCurrentUserId();
+        PhysicalData physicalData = new PhysicalData();
+        BeanUtils.copyProperties(request, physicalData);
+        physicalData.setUserId(userId);
+        physicalDataMapper.insert(physicalData);
+    }
+
+    @Override
+    public Page<PhysicalDataResponse> listPhysicalData(BaseQueryRequest request) {
+        Long userId = getCurrentUserId();
+        Page<PhysicalData> page = new Page<>(request.getPageNum(), request.getPageSize());
+        LambdaQueryWrapper<PhysicalData> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(PhysicalData::getUserId, userId)
+               .ge(request.getStartTime() != null, PhysicalData::getMeasureTime, request.getStartTime())
+               .le(request.getEndTime() != null, PhysicalData::getMeasureTime, request.getEndTime())
+               .orderByDesc(PhysicalData::getMeasureTime);
+
+        Page<PhysicalData> result = physicalDataMapper.selectPage(page, wrapper);
+
+        List<PhysicalDataResponse> responses = result.getRecords().stream()
+                .map(record -> {
+                    PhysicalDataResponse r = new PhysicalDataResponse();
+                    BeanUtils.copyProperties(record, r);
+                    r.setBmi(calculateBMI(record.getHeight(), record.getWeight()));
+                    return r;
+                })
+                .collect(Collectors.toList());
+
+        Page<PhysicalDataResponse> responsePage = new Page<>();
+        responsePage.setRecords(responses);
+        responsePage.setCurrent(result.getCurrent());
+        responsePage.setSize(result.getSize());
+        responsePage.setTotal(result.getTotal());
+        return responsePage;
+    }
+
+    @Override
+    public BigDecimal calculateBMI(BigDecimal height, BigDecimal weight) {
+        if (height == null || weight == null || height.compareTo(BigDecimal.ZERO) <= 0) {
+            return BigDecimal.ZERO;
+        }
+        BigDecimal heightInMeters = height.divide(new BigDecimal("100"), 4, RoundingMode.HALF_UP);
+        return weight.divide(heightInMeters.pow(2), 2, RoundingMode.HALF_UP);
+    }
+
+    private Long getCurrentUserId() {
+        // TODO: replace with actual security context lookup
+        return 1L;
+    }
+}