xgb 6 дней назад
Родитель
Сommit
051d43449e
100 измененных файлов с 4908 добавлено и 757 удалено
  1. 2 0
      fs-company/src/main/resources/logback.xml
  2. 7 0
      fs-service/src/main/java/com/fs/aiChat/mapper/InterestAiChatSessionMapper.java
  3. 2 0
      fs-service/src/main/java/com/fs/company/service/ICompanyUserService.java
  4. 5 0
      fs-service/src/main/java/com/fs/company/service/impl/CompanyUserServiceImpl.java
  5. 78 0
      fs-service/src/main/java/com/fs/his/domain/FsHealthPulse.java
  6. 83 0
      fs-service/src/main/java/com/fs/his/domain/FsHealthSurface.java
  7. 48 0
      fs-service/src/main/java/com/fs/his/domain/FsThirdDeviceData.java
  8. 84 0
      fs-service/src/main/java/com/fs/his/domain/FsUserAdditionalData.java
  9. 74 0
      fs-service/src/main/java/com/fs/his/mapper/FsHealthPulseMapper.java
  10. 77 0
      fs-service/src/main/java/com/fs/his/mapper/FsHealthSurfaceMapper.java
  11. 147 0
      fs-service/src/main/java/com/fs/his/mapper/FsThirdDeviceDataMapper.java
  12. 68 0
      fs-service/src/main/java/com/fs/his/mapper/FsUserAdditionalDataMapper.java
  13. 16 0
      fs-service/src/main/java/com/fs/his/param/FsHealthPulseListUParam.java
  14. 16 0
      fs-service/src/main/java/com/fs/his/param/FsHealthSurfaceListUParam.java
  15. 2 0
      fs-service/src/main/java/com/fs/his/param/FsHealthTongueListUParam.java
  16. 80 0
      fs-service/src/main/java/com/fs/his/service/IFsThirdDeviceDataService.java
  17. 65 0
      fs-service/src/main/java/com/fs/his/service/IFsUserAdditionalDataService.java
  18. 435 0
      fs-service/src/main/java/com/fs/his/service/impl/FsThirdDeviceDataServiceImpl.java
  19. 98 0
      fs-service/src/main/java/com/fs/his/service/impl/FsUserAdditionalDataServiceImpl.java
  20. 69 0
      fs-service/src/main/java/com/fs/his/vo/FsHealthPulseListVO.java
  21. 83 0
      fs-service/src/main/java/com/fs/his/vo/FsHealthSurfaceListVO.java
  22. 544 0
      fs-service/src/main/java/com/fs/watch/calculation/SleepScoreCalculator.java
  23. 4 0
      fs-service/src/main/java/com/fs/watch/domain/DeviceFamily.java
  24. 0 83
      fs-service/src/main/java/com/fs/watch/domain/FsMonitorDataType.java
  25. 68 0
      fs-service/src/main/java/com/fs/watch/domain/SleepStatistics.java
  26. 96 0
      fs-service/src/main/java/com/fs/watch/domain/WatchAudioMsgLog.java
  27. 0 108
      fs-service/src/main/java/com/fs/watch/domain/WatchDeviceBeginnerGuide.java
  28. 56 0
      fs-service/src/main/java/com/fs/watch/domain/WatchDeviceWeek.java
  29. 6 0
      fs-service/src/main/java/com/fs/watch/domain/WatchFsUser.java
  30. 89 0
      fs-service/src/main/java/com/fs/watch/domain/WatchSosCallLogs.java
  31. 25 0
      fs-service/src/main/java/com/fs/watch/domain/WatchUser.java
  32. 4 0
      fs-service/src/main/java/com/fs/watch/domain/vo/AppFsUserHealthReportVo.java
  33. 4 0
      fs-service/src/main/java/com/fs/watch/domain/vo/AppFsUserHealthVo.java
  34. 7 0
      fs-service/src/main/java/com/fs/watch/domain/vo/AppFsUserVo.java
  35. 4 0
      fs-service/src/main/java/com/fs/watch/domain/vo/AppWatchSleepDataVo.java
  36. 27 0
      fs-service/src/main/java/com/fs/watch/domain/vo/DailySleepStatusVo.java
  37. 69 0
      fs-service/src/main/java/com/fs/watch/domain/vo/WatchDeviceInfoAndIotExportVO.java
  38. 0 9
      fs-service/src/main/java/com/fs/watch/domain/vo/WatchDeviceInfoAndUserIdVo.java
  39. 2 0
      fs-service/src/main/java/com/fs/watch/domain/vo/WatchSleepDataVo.java
  40. 12 0
      fs-service/src/main/java/com/fs/watch/domain/vo/WatchSportDataByDateAndThirdDeviceVo.java
  41. 10 0
      fs-service/src/main/java/com/fs/watch/domain/vo/WatchSportRecordVo.java
  42. 2 0
      fs-service/src/main/java/com/fs/watch/mapper/WatchAlarmDataMapper.java
  43. 12 0
      fs-service/src/main/java/com/fs/watch/mapper/WatchAudioMsgLogMapper.java
  44. 4 8
      fs-service/src/main/java/com/fs/watch/mapper/WatchBloodPressureDataMapper.java
  45. 2 0
      fs-service/src/main/java/com/fs/watch/mapper/WatchDeviceInfoClicMapper.java
  46. 4 0
      fs-service/src/main/java/com/fs/watch/mapper/WatchDeviceInfoMapper.java
  47. 68 0
      fs-service/src/main/java/com/fs/watch/mapper/WatchDeviceWeekMapper.java
  48. 2 0
      fs-service/src/main/java/com/fs/watch/mapper/WatchDoctorMapper.java
  49. 2 0
      fs-service/src/main/java/com/fs/watch/mapper/WatchHeartRateDataMapper.java
  50. 36 0
      fs-service/src/main/java/com/fs/watch/mapper/WatchSosCallLogsMapper.java
  51. 2 0
      fs-service/src/main/java/com/fs/watch/mapper/WatchSpo2DataMapper.java
  52. 15 0
      fs-service/src/main/java/com/fs/watch/param/DeviceSendParam.java
  53. 0 1
      fs-service/src/main/java/com/fs/watch/param/WatchChartQueryParam.java
  54. 15 0
      fs-service/src/main/java/com/fs/watch/param/WatchDeviceInfoQueryParam.java
  55. 17 0
      fs-service/src/main/java/com/fs/watch/param/WatchUserByDeviceIdParam.java
  56. 8 0
      fs-service/src/main/java/com/fs/watch/service/DeviceSetUpService.java
  57. 7 0
      fs-service/src/main/java/com/fs/watch/service/WatchAudioMsgLogService.java
  58. 2 1
      fs-service/src/main/java/com/fs/watch/service/WatchBasicInfoService.java
  59. 6 4
      fs-service/src/main/java/com/fs/watch/service/WatchBloodGlucoseDataService.java
  60. 2 0
      fs-service/src/main/java/com/fs/watch/service/WatchBloodPressureDataService.java
  61. 4 3
      fs-service/src/main/java/com/fs/watch/service/WatchDataService.java
  62. 0 24
      fs-service/src/main/java/com/fs/watch/service/WatchDeviceBeginnerGuideService.java
  63. 3 0
      fs-service/src/main/java/com/fs/watch/service/WatchDeviceInfoClicService.java
  64. 2 0
      fs-service/src/main/java/com/fs/watch/service/WatchDeviceInfoService.java
  65. 11 0
      fs-service/src/main/java/com/fs/watch/service/WatchDeviceWeekService.java
  66. 4 2
      fs-service/src/main/java/com/fs/watch/service/WatchHeartRateDataService.java
  67. 1 1
      fs-service/src/main/java/com/fs/watch/service/WatchSleepDataService.java
  68. 33 0
      fs-service/src/main/java/com/fs/watch/service/WatchSosCallLogsService.java
  69. 2 2
      fs-service/src/main/java/com/fs/watch/service/WatchSpo2DataService.java
  70. 3 3
      fs-service/src/main/java/com/fs/watch/service/WatchSportDataService.java
  71. 4 4
      fs-service/src/main/java/com/fs/watch/service/WatchThirdBpDataService.java
  72. 4 4
      fs-service/src/main/java/com/fs/watch/service/WatchThirdUaDataService.java
  73. 6 1
      fs-service/src/main/java/com/fs/watch/service/WatchUserService.java
  74. 63 0
      fs-service/src/main/java/com/fs/watch/service/impl/DeviceSetUpServiceImpl.java
  75. 38 1
      fs-service/src/main/java/com/fs/watch/service/impl/WatchAlarmDataServiceImpl.java
  76. 80 0
      fs-service/src/main/java/com/fs/watch/service/impl/WatchAudioMsgLogServiceImpl.java
  77. 640 31
      fs-service/src/main/java/com/fs/watch/service/impl/WatchBasicInfoServiceImpl.java
  78. 107 24
      fs-service/src/main/java/com/fs/watch/service/impl/WatchBloodGlucoseDataServiceImpl.java
  79. 38 6
      fs-service/src/main/java/com/fs/watch/service/impl/WatchBloodPressureDataServiceImpl.java
  80. 0 4
      fs-service/src/main/java/com/fs/watch/service/impl/WatchContinuousSpo2DataServiceImpl.java
  81. 314 116
      fs-service/src/main/java/com/fs/watch/service/impl/WatchDataServiceImpl.java
  82. 0 79
      fs-service/src/main/java/com/fs/watch/service/impl/WatchDeviceBeginnerGuideServiceImpl.java
  83. 0 4
      fs-service/src/main/java/com/fs/watch/service/impl/WatchDeviceDataServiceImpl.java
  84. 97 0
      fs-service/src/main/java/com/fs/watch/service/impl/WatchDeviceInfoClicServiceImpl.java
  85. 11 3
      fs-service/src/main/java/com/fs/watch/service/impl/WatchDeviceInfoServiceImpl.java
  86. 0 4
      fs-service/src/main/java/com/fs/watch/service/impl/WatchDeviceStatusServiceImpl.java
  87. 20 0
      fs-service/src/main/java/com/fs/watch/service/impl/WatchDeviceWeekServiceImpl.java
  88. 0 4
      fs-service/src/main/java/com/fs/watch/service/impl/WatchEcgDataServiceImpl.java
  89. 0 5
      fs-service/src/main/java/com/fs/watch/service/impl/WatchFatigueDataServiceImpl.java
  90. 46 14
      fs-service/src/main/java/com/fs/watch/service/impl/WatchHeartRateDataServiceImpl.java
  91. 0 5
      fs-service/src/main/java/com/fs/watch/service/impl/WatchMultiLeadsEcgDataServiceImpl.java
  92. 0 5
      fs-service/src/main/java/com/fs/watch/service/impl/WatchPpgDataServiceImpl.java
  93. 15 15
      fs-service/src/main/java/com/fs/watch/service/impl/WatchRriDataServiceImpl.java
  94. 152 63
      fs-service/src/main/java/com/fs/watch/service/impl/WatchSleepDataServiceImpl.java
  95. 72 0
      fs-service/src/main/java/com/fs/watch/service/impl/WatchSosCallLogsServiceImpl.java
  96. 68 28
      fs-service/src/main/java/com/fs/watch/service/impl/WatchSpo2DataServiceImpl.java
  97. 222 57
      fs-service/src/main/java/com/fs/watch/service/impl/WatchSportDataServiceImpl.java
  98. 0 5
      fs-service/src/main/java/com/fs/watch/service/impl/WatchTemperatureDataServiceImpl.java
  99. 0 4
      fs-service/src/main/java/com/fs/watch/service/impl/WatchThirdBkDataServiceImpl.java
  100. 76 22
      fs-service/src/main/java/com/fs/watch/service/impl/WatchThirdBpDataServiceImpl.java

+ 2 - 0
fs-company/src/main/resources/logback.xml

@@ -89,6 +89,8 @@
     <!-- log4j2.xml -->
     <Logger name="com.fs.his.mapper" level="debug"/>
     <Logger name="com.fs.company.mapper" level="debug"/>
+    <Logger name="com.fs.course.mapper" level="debug"/>
+    <Logger name="com.fs.delete.mapper" level="debug"/>
     <Logger name="org.apache.ibatis" level="debug"/>
 
 	<!--系统用户操作日志-->

+ 7 - 0
fs-service/src/main/java/com/fs/aiChat/mapper/InterestAiChatSessionMapper.java

@@ -5,6 +5,7 @@ import com.fs.aiChat.domain.DoctorAiChatLog;
 import com.fs.aiChat.domain.InterestAiChatMsg;
 import com.fs.aiChat.domain.InterestAiSession;
 import com.fs.aiChat.domain.SessionRoleInfo;
+import com.fs.aiChat.param.InterestAiMessage;
 import com.fs.his.domain.FsInterestAiMsg;
 import com.fs.his.domain.FsInterestAiRole;
 import com.fs.his.domain.FsInterestAiSession;
@@ -56,4 +57,10 @@ public interface InterestAiChatSessionMapper extends BaseMapper<DoctorAiChatLog>
 
 
     FsInterestAiRole selectFsInterestAiRoleByRoleId(Long roleId);
+
+    Integer selectSessionIdByUserAndRole(@Param("userId") Long userId, @Param("roleId") Integer roleId);
+
+    FsInterestAiSession selectSessionBySessionId(@Param("sessionId") String sessionId);
+
+    Integer selectAiMsgBySessionIdAndMsg(@Param("param") InterestAiMessage message);
 }

+ 2 - 0
fs-service/src/main/java/com/fs/company/service/ICompanyUserService.java

@@ -144,6 +144,8 @@ public interface ICompanyUserService {
 
     List<CompanyQwUserByIdsVo> selectCompanyQwUserByIds(List<Long> qwUserIdList);
 
+    String selectCompanyUserByIds(String companyUserIds);
+
     /**
      * 查询公司销售列表
      * @param ids 销售ID集合

+ 5 - 0
fs-service/src/main/java/com/fs/company/service/impl/CompanyUserServiceImpl.java

@@ -736,6 +736,11 @@ public class CompanyUserServiceImpl implements ICompanyUserService
         return companyUserMapper.selectCompanyQwUserByIds(ids);
     }
 
+    @Override
+    public String selectCompanyUserByIds(String companyUserIds) {
+        return companyUserMapper.selectCompanyUserNameByIds(companyUserIds);
+    }
+
     /**
      * 新增用户岗位信息
      *

+ 78 - 0
fs-service/src/main/java/com/fs/his/domain/FsHealthPulse.java

@@ -0,0 +1,78 @@
+package com.fs.his.domain;
+
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.fs.common.annotation.Excel;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 脉诊对象 fs_health_pulse
+ *
+ * @author fs
+ * @date 2025-10-11
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class FsHealthPulse extends BaseEntity{
+
+    /** id */
+    private Long id;
+
+    /** 用户id */
+    @Excel(name = "用户id")
+    private Long userId;
+
+    /** 用户名 */
+    @Excel(name = "用户名")
+    private String name;
+
+    /** 性别 */
+    @Excel(name = "性别")
+    private Long sex;
+
+    /** 年龄 */
+    @Excel(name = "年龄")
+    private Long age;
+
+    /** 状态 */
+    @Excel(name = "状态")
+    private Long status;
+
+    /** 左手结果 */
+    @Excel(name = "左手结果")
+    private String leftHandResult;
+
+    /** 右手结果 */
+    @Excel(name = "右手结果")
+    private String rightHandResult;
+
+    /** 脉诊总结 */
+    @Excel(name = "脉诊总结")
+    private String pulseSummary;
+
+    /** 脉诊建议 */
+    @Excel(name = "脉诊建议")
+    private String pulseSuggestions;
+
+    /** 脉诊设备测量ID */
+    @Excel(name = "脉诊设备测量ID")
+    private String measureId;
+
+    /**左手尺寸 */
+    @TableField(exist = false)
+    private String leftHandSize;
+
+     /**右手尺寸 */
+    @TableField(exist = false)
+    private String rightHandSize;
+
+    /**脉诊设备检测结果*/
+    @TableField(exist = false)
+    private Object pulseEquipmentResult;
+
+    /** url */
+    @Excel(name = "url")
+    private String pulseUrl;
+}

+ 83 - 0
fs-service/src/main/java/com/fs/his/domain/FsHealthSurface.java

@@ -0,0 +1,83 @@
+package com.fs.his.domain;
+
+
+import com.fs.common.annotation.Excel;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.Date;
+
+/**
+ * 面诊对象 fs_health_surface
+ *
+ * @author fs
+ * @date 2025-10-10
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class FsHealthSurface extends BaseEntity{
+
+    /** id */
+    private Long id;
+
+    /** 用户id */
+    @Excel(name = "用户id")
+    private Long userId;
+
+    /** 用户名 */
+    @Excel(name = "用户名")
+    private String name;
+
+    /** 性别 */
+    @Excel(name = "性别")
+    private Integer sex;
+
+    /** 年龄 */
+    @Excel(name = "年龄")
+    private Integer age;
+
+    /** 状态 */
+    @Excel(name = "状态")
+    private Integer status;
+
+    /** 面诊图片 */
+    @Excel(name = "面诊图片")
+    private String surfaceUrl;
+
+    /** 肤色的结果 */
+    @Excel(name = "肤色的结果")
+    private String complexionResult;
+
+    /** 肤色结果类型 */
+    @Excel(name = "肤色结果类型")
+    private String complexionTypes;
+
+    /** 区域色斑问题 */
+    @Excel(name = "区域色斑问题")
+    private String spotProblems;
+
+    /** 浮肿问题 */
+    @Excel(name = "浮肿问题")
+    private String swellingProblems;
+
+    /** 光泽度结果 */
+    @Excel(name = "光泽度结果")
+    private String glowResult;
+
+    /** 面诊总结 */
+    @Excel(name = "面诊总结")
+    private String diagnosisSummary;
+
+    /** 健康建议 */
+    @Excel(name = "健康建议")
+    private String healthSuggestions;
+
+    /** 时间 */
+    @Excel(name = "时间")
+    private Date createTime;
+
+    /** 备注 */
+    @Excel(name = "备注")
+    private String remark;
+}

+ 48 - 0
fs-service/src/main/java/com/fs/his/domain/FsThirdDeviceData.java

@@ -0,0 +1,48 @@
+package com.fs.his.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fs.common.annotation.Excel;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 三方设备健康数据对象 fs_third_device_data
+ *
+ * @author fs
+ * @date 2026-03-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class FsThirdDeviceData extends BaseEntity{
+
+    /** 记录id */
+    @TableId
+    private Long id;
+
+    /** 用户id */
+    @Excel(name = "用户id")
+    private Long userId;
+
+    /** 记录类型 0:血压 1:血糖 2:心率  3尿酸 4血氧 */
+    @Excel(name = "记录类型 0:血压 1:血糖 2:心率  3尿酸 4血氧 5步数 6运动 7睡眠")
+    private Integer recordType;
+
+    /** 记录数值 */
+    @Excel(name = "记录数值")
+    private String recordValue;
+
+    /** 记录数值 */
+    @Excel(name = "设备id")
+    private String deviceId;
+
+    /** 设备类型 0小护士设备 1手表 */
+    @Excel(name = "设备类型 0小护士设备 1手表")
+    private Integer deviceType;
+
+    /** 状态 */
+    @Excel(name = "状态")
+    private Integer status;
+
+
+}

+ 84 - 0
fs-service/src/main/java/com/fs/his/domain/FsUserAdditionalData.java

@@ -0,0 +1,84 @@
+package com.fs.his.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fs.common.annotation.Excel;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 设备注册用户额外参数对象 fs_user_additional_data
+ *
+ * @author fs
+ * @date 2025-10-17
+ */
+@Data
+public class FsUserAdditionalData {
+
+    /** $column.columnComment */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    /** 用户名 */
+    @Excel(name = "用户名")
+    private String username;
+
+    /** 用户ID */
+    @Excel(name = "用户ID")
+    private Long fsUserId;
+
+    /** 电话 */
+    @Excel(name = "电话")
+    private String phone;
+
+    /** 身高 */
+    @Excel(name = "身高")
+    private String height;
+
+    /** 体重 */
+    @Excel(name = "体重")
+    private String weight;
+
+    /** 年龄-出生年月 */
+    @Excel(name = "年龄-出生年月")
+    private String age;
+
+    /** 性别 */
+    @Excel(name = "性别")
+    private Integer sex;
+
+    /** 既往病史 */
+    @Excel(name = "既往病史")
+    private String previousMedicalHistory;
+
+    /** 创建时间 **/
+    private Date createTime;
+
+    /** 状态 */
+    @Excel(name = "状态")
+    private Integer status;
+
+    /** 备注 **/
+    private String remark;
+
+    /** 脉诊设备返回H5 **/
+    private String pulseUrl;
+
+    /** 过敏史 */
+    private String historyOfAllergies;
+
+    /** 生活习惯 */
+    private String habit;
+
+    @TableField(exist = false)
+    private List<Object> habitList;
+
+    /** 身份证号码 **/
+    private String idCard;
+
+    private String consultationRecord;
+
+}

+ 74 - 0
fs-service/src/main/java/com/fs/his/mapper/FsHealthPulseMapper.java

@@ -0,0 +1,74 @@
+package com.fs.his.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.his.domain.FsHealthPulse;
+import com.fs.his.param.FsHealthPulseListUParam;
+import com.fs.his.vo.FsHealthPulseListVO;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+/**
+ * 脉诊Mapper接口
+ *
+ * @author fs
+ * @date 2025-10-11
+ */
+public interface FsHealthPulseMapper extends BaseMapper<FsHealthPulse>{
+    /**
+     * 查询脉诊
+     *
+     * @param id 脉诊主键
+     * @return 脉诊
+     */
+    FsHealthPulse selectFsHealthPulseById(Long id);
+
+    /**
+     * 查询脉诊列表
+     *
+     * @param fsHealthPulse 脉诊
+     * @return 脉诊集合
+     */
+    List<FsHealthPulse> selectFsHealthPulseList(FsHealthPulse fsHealthPulse);
+
+    /**
+     * 新增脉诊
+     *
+     * @param fsHealthPulse 脉诊
+     * @return 结果
+     */
+    int insertFsHealthPulse(FsHealthPulse fsHealthPulse);
+
+    /**
+     * 修改脉诊
+     *
+     * @param fsHealthPulse 脉诊
+     * @return 结果
+     */
+    int updateFsHealthPulse(FsHealthPulse fsHealthPulse);
+
+    /**
+     * 删除脉诊
+     *
+     * @param id 脉诊主键
+     * @return 结果
+     */
+    int deleteFsHealthPulseById(Long id);
+
+    /**
+     * 批量删除脉诊
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    int deleteFsHealthPulseByIds(Long[] ids);
+
+    @Select("SELECT * from fs_health_pulse where user_id=#{userId} and status=0 order by create_time desc limit 1")
+    FsHealthPulse queryUserLatestHealthPulse(@Param("userId") Long userId);
+
+    List<FsHealthPulseListVO> selectFsHealthPulseListVO(FsHealthPulseListUParam param);
+
+    List<String> selectListByDateAndUserId(@Param("startDate") String startDate,@Param("endDate") String endDate,@Param("userId") Long userId);
+
+}

+ 77 - 0
fs-service/src/main/java/com/fs/his/mapper/FsHealthSurfaceMapper.java

@@ -0,0 +1,77 @@
+package com.fs.his.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.his.domain.FsHealthSurface;
+import com.fs.his.param.FsHealthSurfaceListUParam;
+import com.fs.his.vo.FsHealthSurfaceListVO;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+
+/**
+ * 面诊Mapper接口
+ *
+ * @author fs
+ * @date 2025-10-10
+ */
+public interface FsHealthSurfaceMapper extends BaseMapper<FsHealthSurface>{
+    /**
+     * 查询面诊
+     *
+     * @param id 面诊主键
+     * @return 面诊
+     */
+    FsHealthSurface selectFsHealthSurfaceById(Long id);
+
+    /**
+     * 查询面诊列表
+     *
+     * @param fsHealthSurface 面诊
+     * @return 面诊集合
+     */
+    List<FsHealthSurface> selectFsHealthSurfaceList(FsHealthSurface fsHealthSurface);
+
+    /**
+     * 新增面诊
+     *
+     * @param fsHealthSurface 面诊
+     * @return 结果
+     */
+    int insertFsHealthSurface(FsHealthSurface fsHealthSurface);
+
+    /**
+     * 修改面诊
+     *
+     * @param fsHealthSurface 面诊
+     * @return 结果
+     */
+    int updateFsHealthSurface(FsHealthSurface fsHealthSurface);
+
+    /**
+     * 删除面诊
+     *
+     * @param id 面诊主键
+     * @return 结果
+     */
+    int deleteFsHealthSurfaceById(Long id);
+
+    /**
+     * 批量删除面诊
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    int deleteFsHealthSurfaceByIds(Long[] ids);
+
+    @Select("SELECT * from fs_health_surface where user_id=#{userId} and status=0 order by create_time desc limit 1")
+    FsHealthSurface queryUserLatestHealthSurface(@Param("userId") Long userId);
+
+    List<FsHealthSurfaceListVO> selectFsHealthSurfaceListVO(FsHealthSurfaceListUParam param);
+
+    List<String> selectListByDateAndUserId(@Param("startDate") String startDate,@Param("endDate") String endDate,@Param("userId") Long userId);
+
+
+
+}

+ 147 - 0
fs-service/src/main/java/com/fs/his/mapper/FsThirdDeviceDataMapper.java

@@ -0,0 +1,147 @@
+package com.fs.his.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.his.domain.FsThirdDeviceData;
+import com.fs.watch.domain.vo.WatchSportRecordVo;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 三方设备健康数据Mapper接口
+ * 
+ * @author fs
+ * @date 2026-03-19
+ */
+public interface FsThirdDeviceDataMapper extends BaseMapper<FsThirdDeviceData>{
+    /**
+     * 查询三方设备健康数据
+     * 
+     * @param id 三方设备健康数据主键
+     * @return 三方设备健康数据
+     */
+    FsThirdDeviceData selectFsThirdDeviceDataById(Long id);
+
+    /**
+     * 查询三方设备健康数据列表
+     * 
+     * @param fsThirdDeviceData 三方设备健康数据
+     * @return 三方设备健康数据集合
+     */
+    List<FsThirdDeviceData> selectFsThirdDeviceDataList(FsThirdDeviceData fsThirdDeviceData);
+
+    /**
+     * 新增三方设备健康数据
+     * 
+     * @param fsThirdDeviceData 三方设备健康数据
+     * @return 结果
+     */
+    int insertFsThirdDeviceData(FsThirdDeviceData fsThirdDeviceData);
+
+    /**
+     * 修改三方设备健康数据
+     * 
+     * @param fsThirdDeviceData 三方设备健康数据
+     * @return 结果
+     */
+    int updateFsThirdDeviceData(FsThirdDeviceData fsThirdDeviceData);
+
+    /**
+     * 删除三方设备健康数据
+     * 
+     * @param id 三方设备健康数据主键
+     * @return 结果
+     */
+    int deleteFsThirdDeviceDataById(Long id);
+
+    /**
+     * 批量删除三方设备健康数据
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    int deleteFsThirdDeviceDataByIds(Long[] ids);
+
+//    Map<String, Integer> countMaxAndMinBpByDate(String currentStartDate, String currentEndDate, String deviceId);
+
+    void insertFsThirdDeviceDataList(@Param("list") List<FsThirdDeviceData> fsThirdDeviceData);
+
+    List<FsThirdDeviceData> getLastData(@Param("userId")Long userId,@Param("deviceType") Integer deviceType,@Param("deviceId") String deviceId);
+
+    /**
+     * 血压
+     * @param startTime
+     * @param endTime
+     * @param deviceId
+     * @return
+     */
+    Map<String, Integer> countMaxAndMinBpByDate(@Param("startTime") String startTime, @Param("endTime") String endTime,
+                                                @Param("deviceId") String deviceId);
+
+    List<FsThirdDeviceData> queryBgByDate(@Param("startTime")String startTime,@Param("endTime") String endTime,
+                                              @Param("deviceId")String deviceId);
+
+    Map<String, Integer> countMaxAndAvgBpByDate(@Param("startTime")String startTime, @Param("endTime") String endTime,
+                                                @Param("deviceId")String deviceId);
+
+    FsThirdDeviceData getFirstDataByDeviceId(@Param("deviceId")String deviceId);
+
+    List<FsThirdDeviceData> queryByMonth(@Param("deviceId")String deviceId, @Param("monthStr")String monthStr,
+                                           @Param("recordType")Integer recordType);
+
+    FsThirdDeviceData getLatest(@Param("deviceId")String deviceId,
+                                @Param("recordType")Integer recordType);
+
+    List<FsThirdDeviceData> selectListByDateAndDeviceIdAndRecordType(@Param("startTime")Date startTime,
+                                                                     @Param("endTime") Date endTime,
+                                                                     @Param("deviceId")String deviceId,
+                                                                     @Param("recordType")Integer recordType,
+                                                                     @Param("status")Integer status);
+
+    List<Map<String, Object>> countByDateAndDeviceIdAndRecordType(@Param("startTime")Date startTime,
+                                                                  @Param("endTime") Date endTime,
+                                                                  @Param("deviceId")String deviceId,
+                                                                  @Param("recordType")Integer recordType,
+                                                                  @Param("status")Integer status);
+
+    int countPageByDateAndDeviceIdAndRecordType(@Param("startTime")Date startTime,
+                                                @Param("endTime") Date endTime,
+                                                @Param("deviceId")String deviceId,
+                                                @Param("recordType")Integer recordType,
+                                                @Param("status")Integer status);
+
+    List<FsThirdDeviceData> queryPageByDateAndDeviceIdAndRecordType(@Param("startTime")Date startTime,
+                                                                    @Param("endTime") Date endTime,
+                                                                    @Param("deviceId")String deviceId,
+                                                                    @Param("recordType")Integer recordType,
+                                                                    @Param("status")Integer status,
+                                                                    @Param("num")Integer num,
+                                                                    @Param("size")Integer size
+                                                                    );
+
+    Float countAvgBpByDate(@Param("startTime") String startTime, @Param("endTime") String endTime, @Param("deviceId") String deviceId);
+
+    WatchSportRecordVo getOtherData(@Param("startTime")Date startTime,
+                                    @Param("endTime") Date endTime,
+                                    @Param("deviceId")String deviceId,
+                                    @Param("recordType")Integer recordType,
+                                    @Param("status")Integer status);
+
+    List<WatchSportRecordVo> queryActivityRecord(@Param("startTime")Date startTime,
+                                                 @Param("endTime") Date endTime,
+                                                 @Param("deviceId")String deviceId,
+                                                 @Param("recordType")Integer recordType,
+                                                 @Param("status")Integer status);
+
+    WatchSportRecordVo getOtherDataOther(@Param("startTime")Date startTime,
+                                         @Param("endTime") Date endTime,
+                                         @Param("deviceId")String deviceId,
+                                         @Param("recordType")Integer recordType);
+
+    List<FsThirdDeviceData> selectListByDateAndDeviceIdAndRecordTypeOther(@Param("startTime")Date startTime,
+                                                                          @Param("endTime") Date endTime,
+                                                                          @Param("deviceId")String deviceId,
+                                                                          @Param("recordType")Integer recordType);
+}

+ 68 - 0
fs-service/src/main/java/com/fs/his/mapper/FsUserAdditionalDataMapper.java

@@ -0,0 +1,68 @@
+package com.fs.his.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.his.domain.FsUserAdditionalData;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+
+/**
+ * 设备注册用户额外参数Mapper接口
+ *
+ * @author fs
+ * @date 2025-10-17
+ */
+public interface FsUserAdditionalDataMapper extends BaseMapper<FsUserAdditionalData>{
+    /**
+     * 查询设备注册用户额外参数
+     *
+     * @param id 设备注册用户额外参数主键
+     * @return 设备注册用户额外参数
+     */
+    FsUserAdditionalData selectFsUserAdditionalDataById(Long id);
+
+    /**
+     * 查询设备注册用户额外参数列表
+     *
+     * @param fsUserAdditionalData 设备注册用户额外参数
+     * @return 设备注册用户额外参数集合
+     */
+    List<FsUserAdditionalData> selectFsUserAdditionalDataList(FsUserAdditionalData fsUserAdditionalData);
+
+    /**
+     * 新增设备注册用户额外参数
+     *
+     * @param fsUserAdditionalData 设备注册用户额外参数
+     * @return 结果
+     */
+    int insertFsUserAdditionalData(FsUserAdditionalData fsUserAdditionalData);
+
+    /**
+     * 修改设备注册用户额外参数
+     *
+     * @param fsUserAdditionalData 设备注册用户额外参数
+     * @return 结果
+     */
+    int updateFsUserAdditionalData(FsUserAdditionalData fsUserAdditionalData);
+
+    /**
+     * 删除设备注册用户额外参数
+     *
+     * @param id 设备注册用户额外参数主键
+     * @return 结果
+     */
+    int deleteFsUserAdditionalDataById(Long id);
+
+    /**
+     * 批量删除设备注册用户额外参数
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    int deleteFsUserAdditionalDataByIds(Long[] ids);
+
+    @Select("select * from fs_user_additional_data where status=0 and fs_user_id=#{fsUserId}")
+    FsUserAdditionalData selectUserByUserId(@Param("fsUserId") Long fsUserId);
+}

+ 16 - 0
fs-service/src/main/java/com/fs/his/param/FsHealthPulseListUParam.java

@@ -0,0 +1,16 @@
+package com.fs.his.param;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class FsHealthPulseListUParam extends BaseParam implements Serializable {
+    /** id */
+    private Long id;
+
+
+    private Long userId;
+
+    private String createDay;
+}

+ 16 - 0
fs-service/src/main/java/com/fs/his/param/FsHealthSurfaceListUParam.java

@@ -0,0 +1,16 @@
+package com.fs.his.param;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class FsHealthSurfaceListUParam extends BaseParam implements Serializable {
+    /** id */
+    private Long id;
+
+
+    private Long userId;
+
+    private String createDay;
+}

+ 2 - 0
fs-service/src/main/java/com/fs/his/param/FsHealthTongueListUParam.java

@@ -12,4 +12,6 @@ public class FsHealthTongueListUParam extends BaseParam implements Serializable
     /** 状态 */
     @Excel(name = "状态")
     private Long userId;
+
+    private String createDay;
 }

+ 80 - 0
fs-service/src/main/java/com/fs/his/service/IFsThirdDeviceDataService.java

@@ -0,0 +1,80 @@
+package com.fs.his.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.his.domain.FsThirdDeviceData;
+import com.fs.watch.domain.vo.WatchSportDataByDateVo;
+import com.fs.watch.domain.vo.WatchSportDetailDataVo;
+import com.fs.watch.domain.vo.WatchSportRecordVo;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 三方设备健康数据Service接口
+ * 
+ * @author fs
+ * @date 2026-03-19
+ */
+public interface IFsThirdDeviceDataService extends IService<FsThirdDeviceData>{
+    /**
+     * 查询三方设备健康数据
+     * 
+     * @param id 三方设备健康数据主键
+     * @return 三方设备健康数据
+     */
+    FsThirdDeviceData selectFsThirdDeviceDataById(Long id);
+
+    /**
+     * 查询三方设备健康数据列表
+     * 
+     * @param fsThirdDeviceData 三方设备健康数据
+     * @return 三方设备健康数据集合
+     */
+    List<FsThirdDeviceData> selectFsThirdDeviceDataList(FsThirdDeviceData fsThirdDeviceData);
+
+    /**
+     * 新增三方设备健康数据
+     * 
+     * @param fsThirdDeviceData 三方设备健康数据
+     * @return 结果
+     */
+    int insertFsThirdDeviceData(FsThirdDeviceData fsThirdDeviceData);
+
+    /**
+     * 修改三方设备健康数据
+     * 
+     * @param fsThirdDeviceData 三方设备健康数据
+     * @return 结果
+     */
+    int updateFsThirdDeviceData(FsThirdDeviceData fsThirdDeviceData);
+
+    /**
+     * 批量删除三方设备健康数据
+     * 
+     * @param ids 需要删除的三方设备健康数据主键集合
+     * @return 结果
+     */
+    int deleteFsThirdDeviceDataByIds(Long[] ids);
+
+    /**
+     * 删除三方设备健康数据信息
+     * 
+     * @param id 三方设备健康数据主键
+     * @return 结果
+     */
+    int deleteFsThirdDeviceDataById(Long id);
+
+    void insertFsThirdDeviceDataList(List<FsThirdDeviceData> fsThirdDeviceData);
+
+    List<FsThirdDeviceData> getLastData(Long userId,Integer deviceType,String deviceId);
+
+    List<WatchSportDataByDateVo> sportDataByDate(Date startTime, Date endTime, String deviceId);
+
+    WatchSportDetailDataVo dataByType(String deviceId, String type);
+
+    public WatchSportRecordVo getOtherData(Date startTime,
+                                           Date endTime,
+                                           String deviceId,
+                                           Integer recordType,
+                                           Integer status);
+}

+ 65 - 0
fs-service/src/main/java/com/fs/his/service/IFsUserAdditionalDataService.java

@@ -0,0 +1,65 @@
+package com.fs.his.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.his.domain.FsUserAdditionalData;
+
+import java.util.List;
+
+/**
+ * 设备注册用户额外参数Service接口
+ *
+ * @author fs
+ * @date 2025-10-17
+ */
+public interface IFsUserAdditionalDataService extends IService<FsUserAdditionalData>{
+    /**
+     * 查询设备注册用户额外参数
+     *
+     * @param id 设备注册用户额外参数主键
+     * @return 设备注册用户额外参数
+     */
+    FsUserAdditionalData selectFsUserAdditionalDataById(Long id);
+
+    /**
+     * 查询设备注册用户额外参数列表
+     *
+     * @param fsUserAdditionalData 设备注册用户额外参数
+     * @return 设备注册用户额外参数集合
+     */
+    List<FsUserAdditionalData> selectFsUserAdditionalDataList(FsUserAdditionalData fsUserAdditionalData);
+
+    /**
+     * 新增设备注册用户额外参数
+     *
+     * @param fsUserAdditionalData 设备注册用户额外参数
+     * @return 结果
+     */
+    int insertFsUserAdditionalData(FsUserAdditionalData fsUserAdditionalData);
+
+    /**
+     * 修改设备注册用户额外参数
+     *
+     * @param fsUserAdditionalData 设备注册用户额外参数
+     * @return 结果
+     */
+    int updateFsUserAdditionalData(FsUserAdditionalData fsUserAdditionalData);
+
+    /**
+     * 批量删除设备注册用户额外参数
+     *
+     * @param ids 需要删除的设备注册用户额外参数主键集合
+     * @return 结果
+     */
+    int deleteFsUserAdditionalDataByIds(Long[] ids);
+
+    /**
+     * 删除设备注册用户额外参数信息
+     *
+     * @param id 设备注册用户额外参数主键
+     * @return 结果
+     */
+    int deleteFsUserAdditionalDataById(Long id);
+
+    FsUserAdditionalData selectUserByUserId(Long fsUserId);
+
+}

+ 435 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsThirdDeviceDataServiceImpl.java

@@ -0,0 +1,435 @@
+package com.fs.his.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fs.common.utils.DateUtils;
+import com.fs.common.utils.StringUtils;
+import com.fs.his.domain.FsThirdDeviceData;
+import com.fs.his.mapper.FsThirdDeviceDataMapper;
+import com.fs.his.service.IFsThirdDeviceDataService;
+import com.fs.watch.domain.vo.WatchSportDataByDateAndThirdDeviceVo;
+import com.fs.watch.domain.vo.WatchSportDataByDateVo;
+import com.fs.watch.domain.vo.WatchSportDetailDataVo;
+import com.fs.watch.domain.vo.WatchSportRecordVo;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.DayOfWeek;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.TemporalAdjusters;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 三方设备健康数据Service业务层处理
+ * 
+ * @author fs
+ * @date 2026-03-19
+ */
+@Service
+public class FsThirdDeviceDataServiceImpl extends ServiceImpl<FsThirdDeviceDataMapper, FsThirdDeviceData> implements IFsThirdDeviceDataService {
+
+    /**
+     * 查询三方设备健康数据
+     * 
+     * @param id 三方设备健康数据主键
+     * @return 三方设备健康数据
+     */
+    @Override
+    public FsThirdDeviceData selectFsThirdDeviceDataById(Long id)
+    {
+        return baseMapper.selectFsThirdDeviceDataById(id);
+    }
+
+    /**
+     * 查询三方设备健康数据列表
+     * 
+     * @param fsThirdDeviceData 三方设备健康数据
+     * @return 三方设备健康数据
+     */
+    @Override
+    public List<FsThirdDeviceData> selectFsThirdDeviceDataList(FsThirdDeviceData fsThirdDeviceData)
+    {
+        return baseMapper.selectFsThirdDeviceDataList(fsThirdDeviceData);
+    }
+
+    /**
+     * 新增三方设备健康数据
+     * 
+     * @param fsThirdDeviceData 三方设备健康数据
+     * @return 结果
+     */
+    @Override
+    public int insertFsThirdDeviceData(FsThirdDeviceData fsThirdDeviceData)
+    {
+        fsThirdDeviceData.setCreateTime(DateUtils.getNowDate());
+        return baseMapper.insertFsThirdDeviceData(fsThirdDeviceData);
+    }
+
+    /**
+     * 修改三方设备健康数据
+     * 
+     * @param fsThirdDeviceData 三方设备健康数据
+     * @return 结果
+     */
+    @Override
+    public int updateFsThirdDeviceData(FsThirdDeviceData fsThirdDeviceData)
+    {
+        return baseMapper.updateFsThirdDeviceData(fsThirdDeviceData);
+    }
+
+    /**
+     * 批量删除三方设备健康数据
+     * 
+     * @param ids 需要删除的三方设备健康数据主键
+     * @return 结果
+     */
+    @Override
+    public int deleteFsThirdDeviceDataByIds(Long[] ids)
+    {
+        return baseMapper.deleteFsThirdDeviceDataByIds(ids);
+    }
+
+    /**
+     * 删除三方设备健康数据信息
+     * 
+     * @param id 三方设备健康数据主键
+     * @return 结果
+     */
+    @Override
+    public int deleteFsThirdDeviceDataById(Long id)
+    {
+        return baseMapper.deleteFsThirdDeviceDataById(id);
+    }
+
+    @Override
+    public void insertFsThirdDeviceDataList(List<FsThirdDeviceData> fsThirdDeviceData) {
+        baseMapper.insertFsThirdDeviceDataList(fsThirdDeviceData);
+    }
+
+    @Override
+    public List<FsThirdDeviceData> getLastData(Long userId,Integer deviceType,String deviceId) {
+        return baseMapper.getLastData(userId,deviceType,deviceId);
+    }
+
+    /**
+     * 查询运动
+     * @param startTime
+     * @param endTime
+     * @param deviceId
+     * @return
+     */
+    @Override
+    public List<WatchSportDataByDateVo> sportDataByDate(Date startTime, Date endTime, String deviceId) {
+        //活动
+        ArrayList<FsThirdDeviceData> activity = new ArrayList<>();
+        List<FsThirdDeviceData> activity1 = baseMapper.selectListByDateAndDeviceIdAndRecordType(startTime, endTime, deviceId,5,null);
+        activity.addAll(activity1);
+//        activity.addAll(activity2);
+        //解析成活动数据
+        if(!activity.isEmpty()){
+            ArrayList<WatchSportDataByDateAndThirdDeviceVo> vos = new ArrayList<>();
+            for (FsThirdDeviceData fsThirdDeviceData : activity) {
+                String recordValue = fsThirdDeviceData.getRecordValue();
+                if (StringUtils.isNotBlank(recordValue)) {
+                    WatchSportDataByDateAndThirdDeviceVo data = new WatchSportDataByDateAndThirdDeviceVo();
+                    JSONObject jsonObject = JSONObject.parseObject(recordValue);
+                    data.setDeviceId(jsonObject.getString("deviceId"));
+                    data.setStep(Integer.valueOf(jsonObject.get("steps").toString()));
+                    data.setDistance(Float.parseFloat(jsonObject.get("distance").toString())*1000);
+                    data.setCalorie(Float.valueOf(jsonObject.get("calories").toString()));
+//                    data.setType(getActivityType(Integer.valueOf(jsonObject.get("sportType").toString())));
+                    data.setState(0);
+                    data.setCreateTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",fsThirdDeviceData.getCreateTime()));
+                    vos.add(data);
+
+                }
+            }
+            // 计算时间差(以毫秒为单位)
+            long timeDifferenceInMillis = endTime.getTime() - startTime.getTime();
+
+            // 判断是一天还是一周
+            if (timeDifferenceInMillis > 24 * 60 * 60 * 1000) {
+                // 一周的数据(按天统计)
+                return getWeekData(vos, LocalDateTime.ofInstant(startTime.toInstant(), ZoneId.systemDefault()),
+                        LocalDateTime.ofInstant(endTime.toInstant(), ZoneId.systemDefault()));
+            } else {
+                // 一天的数据(按小时统计)
+                return getDayData(vos);
+            }
+        }
+        return null;
+
+    }
+
+    @Override
+    public WatchSportDetailDataVo dataByType(String deviceId, String type) {
+        if (StringUtils.isNotBlank(deviceId)) {
+            //详情
+            WatchSportDetailDataVo vo = new WatchSportDetailDataVo();
+            ArrayList<WatchSportDataByDateVo> list = new ArrayList<>();
+            //1.总计 距离 次数
+            WatchSportRecordVo recordVo = null; //总计只有一条数据
+            List<FsThirdDeviceData> otherDetail = null;
+            if ("其他运动".equals(type)) {
+                //游泳", "登山", "骑行", "跑步", "球类", "健走", "走路"
+                //25,17,1,9,21,5,13
+                recordVo = baseMapper.getOtherDataOther(null, null, deviceId, 6);
+                otherDetail = baseMapper.selectListByDateAndDeviceIdAndRecordTypeOther(null, null, deviceId, 6);
+            } else {
+                Integer sportType = getSportType(type);
+                //步数
+                recordVo = baseMapper.getOtherData(null, null, deviceId, 6, sportType);
+                //2.详情
+                otherDetail = baseMapper.selectListByDateAndDeviceIdAndRecordType(null, null, deviceId, 6, sportType);
+            }
+            long otherTime = 0L;
+            if (otherDetail != null && !otherDetail.isEmpty()) {
+                for (FsThirdDeviceData fsThirdDeviceData : otherDetail) {
+                    String recordValue = fsThirdDeviceData.getRecordValue();
+                    if (StringUtils.isNotBlank(recordValue)) {
+                        JSONObject jsonObject = JSONObject.parseObject(recordValue);
+                        float distance = Float.parseFloat(jsonObject.get("distance").toString());
+                        Float calories = Float.valueOf(jsonObject.get("calories").toString());
+                        String createTime = DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", fsThirdDeviceData.getCreateTime());
+                        float duration = Float.parseFloat(jsonObject.get("duration").toString());
+                        otherTime = otherTime + Long.parseLong(jsonObject.get("duration").toString());
+
+                        //详情
+                        WatchSportDataByDateVo watchSportDataByDateVo = new WatchSportDataByDateVo();
+                        watchSportDataByDateVo.setCreateTime(createTime);
+                        watchSportDataByDateVo.setCalorie(calories);
+                        watchSportDataByDateVo.setDistance(distance);
+                        watchSportDataByDateVo.setTime(duration);
+                        watchSportDataByDateVo.setSpeed((float) Math.round((distance)/(duration/3600)));
+                        list.add(watchSportDataByDateVo);
+                    }
+                }
+            }
+            if (recordVo != null) {
+                vo.setDistanceTotal(recordVo.getDistance()); //换算公里 保留两位
+                vo.setCountTotal(recordVo.getCount());
+                //1.2时长
+                BigDecimal timeInMinutes = new BigDecimal(otherTime)
+                        .divide(new BigDecimal(3600), 2, RoundingMode.HALF_UP);
+                vo.setTimeTotal(Float.valueOf(timeInMinutes+""));
+            }
+            vo.setList(list);
+            return vo;
+        }
+        return null;
+    }
+
+    private String getActivityType(Integer sportType) {
+        if (sportType == null) {
+            return null;
+        }
+        switch (sportType) {
+            case 1:
+                return "骑行";
+            case 5:
+                return "户外跑/健走";
+            case 9:
+                return "室内跑";
+            case 13:
+                return "步行";
+            case 17:
+                return "爬山";
+            case 21:
+                return "篮球";
+            case 25:
+                return "游泳";
+            case 29:
+                return "羽毛球";
+            case 33:
+                return "足球";
+            case 37:
+                return "椭圆机";
+            case 41:
+                return "瑜伽";
+            case 45:
+                return "乒乓球";
+            case 49:
+                return "跳绳";
+            case 53:
+                return "划船机";
+            case 65:
+                return "自由训练";
+            case 69:
+                return "网球";
+            case 85:
+                return "自由运动";
+            case 89:
+                return "力量训练";
+            case 105:
+                return "舞蹈";
+            case 109:
+                return "呼啦圈";
+            case 113:
+                return "高尔夫";
+            default:
+                return null;
+        }
+    }
+
+    private Integer getSportType(String activityType) {
+        //游泳", "登山", "骑行", "跑步", "球类", "健走", "走路" 25,17,1,9,21,5,13
+        if (activityType == null || activityType.isEmpty()) {
+            return null;
+        }
+        switch (activityType) {
+            case "骑行":
+                return 1;
+            case "健步走":
+                return 5;
+            case "跑步":
+                return 9;
+            case "走路":
+                return 13;
+            case "登山":
+                return 17;
+            case "球类":
+                return 21;
+            case "游泳":
+                return 25;
+            case "羽毛球":
+                return 29;
+            case "足球":
+                return 33;
+            case "椭圆机":
+                return 37;
+            case "瑜伽":
+                return 41;
+            case "乒乓球":
+                return 45;
+            case "跳绳":
+                return 49;
+            case "划船机":
+                return 53;
+            case "自由训练":
+                return 65;
+            case "网球":
+                return 69;
+            case "自由运动":
+                return 85;
+            case "力量训练":
+                return 89;
+            case "舞蹈":
+                return 105;
+            case "呼啦圈":
+                return 109;
+            case "高尔夫":
+                return 113;
+            default:
+                return null;
+
+        }
+    }
+
+    private List<WatchSportDataByDateVo> getWeekData(List<WatchSportDataByDateAndThirdDeviceVo> activity, LocalDateTime startTime, LocalDateTime endTime) {
+        // 按天分组
+        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        Map<LocalDate, List<WatchSportDataByDateAndThirdDeviceVo>> groupedByDate = activity.stream()
+                .collect(Collectors.groupingBy(data -> {
+                    LocalDateTime dateTime = LocalDateTime.parse(data.getCreateTime(), dateTimeFormatter);
+                    return dateTime.toLocalDate();
+                }));
+
+        // 确定一周的起始日期(周一)
+        LocalDate startOfWeek = startTime.toLocalDate().with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
+        // 初始化结果列表,确保返回7天的数据
+        List<WatchSportDataByDateVo> result = new ArrayList<>();
+        for (int i = 0; i < 7; i++) {
+            LocalDate currentDate = startOfWeek.plusDays(i);
+//            LocalDate currentDate = startDate.plusDays(i);
+            List<WatchSportDataByDateAndThirdDeviceVo> dayData = groupedByDate.getOrDefault(currentDate, Collections.emptyList());
+
+            // 汇总每天数据
+            float totalDistance = (float) dayData.stream()
+                    .mapToDouble(data -> Optional.ofNullable(data.getDistance()).orElse(0f)).sum();
+            float totalCalorie = (float) dayData.stream()
+                    .mapToDouble(data -> Optional.ofNullable(data.getCalorie()).orElse(0f)).sum();
+            float totalTime = (float) dayData.stream()
+                    .mapToDouble(data -> Optional.ofNullable(data.getDuration()).orElse(0f)).sum();
+
+
+            // 创建统计对象
+            WatchSportDataByDateVo vo = new WatchSportDataByDateVo();
+            Float distance = Math.round(totalDistance/1000 * 100) / 100f;
+            vo.setDistance(distance); //换算公里
+            vo.setCalorie(Math.round(totalCalorie * 100) / 100f);
+            Float time = Math.round(totalTime * 100) / 100f;
+            if (time <=0){
+                time = 24*60*60f;
+            }
+            vo.setTime(time); //秒
+            float avgSpeed = time > 0 ? distance / (totalTime/3600) : 0;
+            vo.setSpeed(Math.round(avgSpeed * 100) / 100f);
+            result.add(vo);
+        }
+        return result;
+    }
+
+    private List<WatchSportDataByDateVo> getDayData(List<WatchSportDataByDateAndThirdDeviceVo> activity) {
+        // 提前分配24小时结果数组
+        WatchSportDataByDateVo[] result = new WatchSportDataByDateVo[24];
+        for (int i = 0; i < 24; i++) {
+            result[i] = new WatchSportDataByDateVo(); // 初始化每小时的默认值
+            result[i].setDistance(0f);
+            result[i].setCalorie(0f);
+            result[i].setTime(0f); // 默认总时间为0秒
+            result[i].setSpeed(0f);
+        }
+
+        // 定义时间解析器
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+        // 按小时分组并直接统计
+        for (WatchSportDataByDateAndThirdDeviceVo data : activity) {
+            // 解析 createTime 的小时
+            LocalDateTime dateTime = LocalDateTime.parse(data.getCreateTime(), formatter);
+            int hour = dateTime.getHour();
+
+            // 获取对应小时的统计对象
+            WatchSportDataByDateVo vo = result[hour];
+
+            // 累加距离和卡路里
+            float dis = vo.getDistance() + ((Optional.ofNullable(data.getDistance()).orElse(0f)) / 1000);
+            float cal = vo.getCalorie() + Optional.ofNullable(data.getCalorie()).orElse(0f);
+            float time = vo.getTime() + Optional.ofNullable(data.getDuration()).orElse(0f);
+            vo.setDistance(Math.round(dis * 100) / 100f); //换算公里
+            vo.setCalorie(Math.round(cal * 100) / 100f);
+            // 假设每条记录表示1分钟运动///todo
+//            vo.setTime(vo.getTime() + 1f / 60); // 累加时间,单位为小时
+            if (time <= 0) {
+                time = 3600;
+            }
+            vo.setTime(time); // 累加时间,单位秒
+        }
+
+
+        // 计算每小时的平均速度
+        for (WatchSportDataByDateVo vo : result) {
+            if (vo.getTime() > 0) {
+                vo.setSpeed(Math.round((vo.getDistance() / (vo.getTime()/3600)) * 100) / 100f); // 平均速度 = 距离 / 时间
+            }
+        }
+        return Arrays.asList(result);
+    }
+
+    @Override
+    public WatchSportRecordVo getOtherData(Date startTime,
+                                    Date endTime,
+                                    String deviceId,
+                                    Integer recordType,
+                                    Integer status){
+        return baseMapper.getOtherData(startTime,endTime,deviceId,recordType,status);
+
+    }
+
+
+}

+ 98 - 0
fs-service/src/main/java/com/fs/his/service/impl/FsUserAdditionalDataServiceImpl.java

@@ -0,0 +1,98 @@
+package com.fs.his.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fs.common.utils.DateUtils;
+import com.fs.his.domain.FsUserAdditionalData;
+import com.fs.his.mapper.FsUserAdditionalDataMapper;
+import com.fs.his.service.IFsUserAdditionalDataService;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * 设备注册用户额外参数Service业务层处理
+ *
+ * @author fs
+ * @date 2025-10-17
+ */
+@Service
+public class FsUserAdditionalDataServiceImpl extends ServiceImpl<FsUserAdditionalDataMapper, FsUserAdditionalData> implements IFsUserAdditionalDataService {
+
+    /**
+     * 查询设备注册用户额外参数
+     *
+     * @param id 设备注册用户额外参数主键
+     * @return 设备注册用户额外参数
+     */
+    @Override
+    public FsUserAdditionalData selectFsUserAdditionalDataById(Long id)
+    {
+        return baseMapper.selectFsUserAdditionalDataById(id);
+    }
+
+    /**
+     * 查询设备注册用户额外参数列表
+     *
+     * @param fsUserAdditionalData 设备注册用户额外参数
+     * @return 设备注册用户额外参数
+     */
+    @Override
+    public List<FsUserAdditionalData> selectFsUserAdditionalDataList(FsUserAdditionalData fsUserAdditionalData)
+    {
+        return baseMapper.selectFsUserAdditionalDataList(fsUserAdditionalData);
+    }
+
+    /**
+     * 新增设备注册用户额外参数
+     *
+     * @param fsUserAdditionalData 设备注册用户额外参数
+     * @return 结果
+     */
+    @Override
+    public int insertFsUserAdditionalData(FsUserAdditionalData fsUserAdditionalData)
+    {
+        fsUserAdditionalData.setCreateTime(DateUtils.getNowDate());
+        return baseMapper.insertFsUserAdditionalData(fsUserAdditionalData);
+    }
+
+    /**
+     * 修改设备注册用户额外参数
+     *
+     * @param fsUserAdditionalData 设备注册用户额外参数
+     * @return 结果
+     */
+    @Override
+    public int updateFsUserAdditionalData(FsUserAdditionalData fsUserAdditionalData)
+    {
+        return baseMapper.updateFsUserAdditionalData(fsUserAdditionalData);
+    }
+
+    /**
+     * 批量删除设备注册用户额外参数
+     *
+     * @param ids 需要删除的设备注册用户额外参数主键
+     * @return 结果
+     */
+    @Override
+    public int deleteFsUserAdditionalDataByIds(Long[] ids)
+    {
+        return baseMapper.deleteFsUserAdditionalDataByIds(ids);
+    }
+
+    /**
+     * 删除设备注册用户额外参数信息
+     *
+     * @param id 设备注册用户额外参数主键
+     * @return 结果
+     */
+    @Override
+    public int deleteFsUserAdditionalDataById(Long id)
+    {
+        return baseMapper.deleteFsUserAdditionalDataById(id);
+    }
+
+    @Override
+    public FsUserAdditionalData selectUserByUserId(Long fsUserId) {
+        return baseMapper.selectUserByUserId(fsUserId);
+    }
+}

+ 69 - 0
fs-service/src/main/java/com/fs/his/vo/FsHealthPulseListVO.java

@@ -0,0 +1,69 @@
+package com.fs.his.vo;
+
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fs.common.annotation.Excel;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 脉诊对象 fs_health_pulse
+ *
+ * @author fs
+ * @date 2025-10-11
+ */
+@Data
+public class FsHealthPulseListVO extends BaseEntity{
+
+    /** id */
+    private Long id;
+
+    /** 用户id */
+    @Excel(name = "用户id")
+    private Long userId;
+
+    /** 用户名 */
+    @Excel(name = "用户名")
+    private String name;
+
+    /** 性别 */
+    @Excel(name = "性别")
+    private Long sex;
+
+    /** 年龄 */
+    @Excel(name = "年龄")
+    private Long age;
+
+    /** 状态 */
+    @Excel(name = "状态")
+    private Long status;
+
+    /** 左手结果 */
+    @Excel(name = "左手结果")
+    private String leftHandResult;
+
+    /** 右手结果 */
+    @Excel(name = "右手结果")
+    private String rightHandResult;
+
+    /** 脉诊总结 */
+    @Excel(name = "脉诊总结")
+    private String pulseSummary;
+
+    /** 脉诊建议 */
+    @Excel(name = "脉诊建议")
+    private String pulseSuggestions;
+
+    /** 脉诊设备测量ID */
+    @Excel(name = "脉诊设备测量ID")
+    private String measureId;
+
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    /** url */
+    @Excel(name = "url")
+    private String pulseUrl;
+}

+ 83 - 0
fs-service/src/main/java/com/fs/his/vo/FsHealthSurfaceListVO.java

@@ -0,0 +1,83 @@
+package com.fs.his.vo;
+
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fs.common.annotation.Excel;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 面诊对象 fs_health_surface
+ *
+ * @author fs
+ * @date 2025-10-10
+ */
+@Data
+public class FsHealthSurfaceListVO extends BaseEntity{
+
+    /** id */
+    private Long id;
+
+    /** 用户id */
+    @Excel(name = "用户id")
+    private Long userId;
+
+    /** 用户名 */
+    @Excel(name = "用户名")
+    private String name;
+
+    /** 性别 */
+    @Excel(name = "性别")
+    private Integer sex;
+
+    /** 年龄 */
+    @Excel(name = "年龄")
+    private Integer age;
+
+    /** 状态 */
+    @Excel(name = "状态")
+    private Integer status;
+
+    /** 面诊图片 */
+    @Excel(name = "面诊图片")
+    private String surfaceUrl;
+
+    /** 肤色的结果 */
+    @Excel(name = "肤色的结果")
+    private String complexionResult;
+
+    /** 肤色结果类型 */
+    @Excel(name = "肤色结果类型")
+    private String complexionTypes;
+
+    /** 区域色斑问题 */
+    @Excel(name = "区域色斑问题")
+    private String spotProblems;
+
+    /** 浮肿问题 */
+    @Excel(name = "浮肿问题")
+    private String swellingProblems;
+
+    /** 光泽度结果 */
+    @Excel(name = "光泽度结果")
+    private String glowResult;
+
+    /** 面诊总结 */
+    @Excel(name = "面诊总结")
+    private String diagnosisSummary;
+
+    /** 健康建议 */
+    @Excel(name = "健康建议")
+    private String healthSuggestions;
+
+    /** 时间 */
+    @Excel(name = "时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    /** 备注 */
+    @Excel(name = "备注")
+    private String remark;
+}

+ 544 - 0
fs-service/src/main/java/com/fs/watch/calculation/SleepScoreCalculator.java

@@ -0,0 +1,544 @@
+package com.fs.watch.calculation;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fs.common.utils.DateUtils;
+import com.fs.his.domain.FsThirdDeviceData;
+import com.fs.his.mapper.FsThirdDeviceDataMapper;
+import com.fs.watch.domain.SleepSection;
+import com.fs.watch.domain.SleepStatistics;
+import com.fs.watch.domain.vo.AppWatchSleepDataVo;
+import com.fs.watch.domain.vo.DailySleepStatusVo;
+import com.fs.watch.enums.WatchSleepStatusEnum;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.stereotype.Component;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.ExecutorCompletionService;
+import java.util.concurrent.Future;
+
+/**
+ * 睡眠评分计算工具类
+ */
+@Slf4j
+@Component
+public class SleepScoreCalculator {
+
+    // 类型常量
+    private static final int TYPE_DEEP_SLEEP = 3;      // 深睡
+    private static final int TYPE_LIGHT_SLEEP = 4;     // 浅睡
+    private static final int TYPE_AWAKE = 6;           // 清醒
+    private static final int TYPE_REM = 7;             // 快速眼动
+    @Autowired
+    private ThreadPoolTaskExecutor threadPoolTaskExecutor;  // 现在可以注入了
+
+    @Autowired
+    private FsThirdDeviceDataMapper sleepDataMapper;
+
+    /**
+     * 计算睡眠评分
+     * @param sleepRecords 睡眠记录列表
+     * @return 睡眠评分(0-100分)
+     */
+    public static int calculateSleepScore(List<FsThirdDeviceData> sleepRecords) {
+        if (sleepRecords == null || sleepRecords.isEmpty()) {
+            return 0;
+        }
+
+        long totalDuration = 0;      // 总睡眠时长(毫秒)
+        long deepSleepDuration = 0;   // 深睡时长(毫秒)
+        long lightSleepDuration = 0;  // 浅睡时长(毫秒)
+        long awakeDuration = 0;       // 清醒时长(毫秒)
+        int awakeCount = 0;           // 清醒次数
+
+        for (FsThirdDeviceData record : sleepRecords) {
+            String recordValue = record.getRecordValue();
+            if (recordValue == null || recordValue.isEmpty()) {
+                continue;
+            }
+
+            try {
+                JSONObject json = JSONObject.parseObject(recordValue);
+                Long startTime = json.getLong("startTime");
+                Long endTime = json.getLong("endTime");
+                Integer status = json.getInteger("status");
+
+                if (startTime == null || endTime == null || status == null) {
+                    continue;
+                }
+
+                long duration = endTime - startTime;
+                totalDuration += duration;
+
+                switch (status) {
+                    case 1: // 深睡
+                        deepSleepDuration += duration;
+                        break;
+                    case 2: // 浅睡
+                        lightSleepDuration += duration;
+                        break;
+                    case 3: // 清醒
+                        awakeDuration += duration;
+                        awakeCount++;
+                        break;
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+        // 计算各维度得分
+        int durationScore = calculateDurationScore(totalDuration);
+        int deepSleepRatioScore = calculateDeepSleepRatioScore(deepSleepDuration, totalDuration);
+        int lightSleepRatioScore = calculateLightSleepRatioScore(lightSleepDuration, totalDuration);
+        int awakeScore = calculateAwakeScore(awakeDuration, awakeCount, totalDuration);
+
+        // 总分 = 时长分*30% + 深睡比例分*35% + 浅睡比例分*15% + 清醒分*20%
+        int totalScore = (int)(durationScore * 0.30
+                + deepSleepRatioScore * 0.35
+                + lightSleepRatioScore * 0.15
+                + awakeScore * 0.20);
+
+        return Math.min(100, Math.max(0, totalScore));
+    }
+
+    /**
+     * 计算详细的睡眠统计数据
+     * @param sleepRecords 睡眠记录列表
+     * @return 睡眠统计信息
+     */
+    public static SleepStatistics calculateDetailedStatistics(List<FsThirdDeviceData> sleepRecords) {
+        SleepStatistics statistics = new SleepStatistics();
+
+        if (sleepRecords == null || sleepRecords.isEmpty()) {
+            return statistics;
+        }
+
+        long totalDuration = 0;
+        long deepSleepDuration = 0;
+        long lightSleepDuration = 0;
+        long awakeDuration = 0;
+        long remDuration = 0;
+        int deepSleepCount = 0;
+        int lightSleepCount = 0;
+        int awakeCount = 0;
+        int remCount = 0;
+
+        List<SleepSection> sleepSectionList = new ArrayList<>();
+        for (FsThirdDeviceData record : sleepRecords) {
+            String recordValue = record.getRecordValue();
+            if (recordValue == null || recordValue.isEmpty()) {
+                continue;
+            }
+
+            try {
+                JSONObject json = JSONObject.parseObject(recordValue);
+                Long startTime = json.getLong("startTime");
+                Long endTime = json.getLong("endTime");
+                Integer status = json.getInteger("status");
+
+                if (startTime == null || endTime == null || status == null) {
+                    continue;
+                }
+
+                long duration = endTime - startTime;
+                totalDuration += duration;
+
+                // 创建睡眠区间
+                SleepSection section = new SleepSection();
+                // 将时间戳转换为指定格式
+                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                section.setStart(sdf.format(new Date(startTime)));
+                section.setEnd(sdf.format(new Date(endTime)));
+
+                // status 转换为 type
+                // status: 1深睡, 2浅睡, 3清醒
+                // type: 3深睡, 4浅睡, 6清醒, 7快速眼动
+                Integer type = convertStatusToType(status);
+                section.setType(type);
+                sleepSectionList.add(section);
+
+                switch (status) {
+                    case 1: // 深睡
+                        deepSleepDuration += duration;
+                        deepSleepCount++;
+                        break;
+                    case 2: // 浅睡
+                        lightSleepDuration += duration;
+                        lightSleepCount++;
+                        break;
+                    case 3: // 清醒
+                        awakeDuration += duration;
+                        awakeCount++;
+                        break;
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+        // 设置统计数据
+        statistics.setTotalDuration(totalDuration);
+        statistics.setTotalSleepHours(totalDuration / 3600000.0);
+        statistics.setDeepSleepDuration(deepSleepDuration);
+        statistics.setDeepSleepHours(deepSleepDuration / 3600000.0);
+        statistics.setDeepSleepCount(deepSleepCount);
+        statistics.setLightSleepDuration(lightSleepDuration);
+        statistics.setLightSleepHours(lightSleepDuration / 3600000.0);
+        statistics.setLightSleepCount(lightSleepCount);
+        statistics.setAwakeDuration(awakeDuration);
+        statistics.setAwakeHours(awakeDuration / 3600000.0);
+        statistics.setAwakeCount(awakeCount);
+        statistics.setRemDuration(remDuration);
+        statistics.setRemHours(remDuration / 3600000.0);
+        statistics.setRemCount(remCount);
+        statistics.setSleepSection(sleepSectionList);
+
+        if (totalDuration > 0) {
+            statistics.setDeepSleepRatio((double) deepSleepDuration / totalDuration);
+            statistics.setLightSleepRatio((double) lightSleepDuration / totalDuration);
+            statistics.setAwakeRatio((double) awakeDuration / totalDuration);
+            statistics.setRemRatio((double) remDuration / totalDuration);
+        }
+
+        return statistics;
+    }
+
+    /**
+     * 将 status 转换为 type
+     * @param status 1:深睡 2:浅睡 3:清醒
+     * @return type 3:深睡 4:浅睡 6:清醒 7:快速眼动
+     */
+    private static Integer convertStatusToType(Integer status) {
+        if (status == null) {
+            return 6; // 默认清醒
+        }
+        switch (status) {
+            case 1:
+                return TYPE_DEEP_SLEEP;  // 深睡
+            case 2:
+                return TYPE_LIGHT_SLEEP; // 浅睡
+            case 3:
+                return TYPE_AWAKE;       // 清醒
+            default:
+                return TYPE_AWAKE;
+        }
+    }
+
+
+    /**
+     * 睡眠时长评分(满分100分)
+     * 标准:成人建议7-8小时
+     */
+    private static int calculateDurationScore(long totalDurationMs) {
+        double hours = totalDurationMs / 3600000.0;
+
+        if (hours >= 7 && hours <= 8) {
+            return 100;
+        } else if (hours >= 6 && hours < 7) {
+            return 80;
+        } else if (hours >= 8 && hours <= 9) {
+            return 85;
+        } else if (hours >= 5 && hours < 6) {
+            return 60;
+        } else if (hours > 9 && hours <= 10) {
+            return 70;
+        } else if (hours >= 4 && hours < 5) {
+            return 40;
+        } else if (hours > 10) {
+            return 50;
+        } else {
+            return 20;
+        }
+    }
+
+    /**
+     * 深睡比例评分(满分100分)
+     * 标准:深睡应占总睡眠时长的20-25%
+     */
+    private static int calculateDeepSleepRatioScore(long deepSleepDuration, long totalDuration) {
+        if (totalDuration <= 0) {
+            return 0;
+        }
+
+        double ratio = (double) deepSleepDuration / totalDuration;
+
+        if (ratio >= 0.20 && ratio <= 0.25) {
+            return 100;
+        } else if (ratio >= 0.15 && ratio < 0.20) {
+            return 80;
+        } else if (ratio > 0.25 && ratio <= 0.30) {
+            return 85;
+        } else if (ratio >= 0.10 && ratio < 0.15) {
+            return 60;
+        } else if (ratio > 0.30 && ratio <= 0.35) {
+            return 70;
+        } else if (ratio >= 0.05 && ratio < 0.10) {
+            return 40;
+        } else {
+            return 20;
+        }
+    }
+
+    /**
+     * 浅睡比例评分(满分100分)
+     * 标准:浅睡应占总睡眠时长的50-60%
+     */
+    private static int calculateLightSleepRatioScore(long lightSleepDuration, long totalDuration) {
+        if (totalDuration <= 0) {
+            return 0;
+        }
+
+        double ratio = (double) lightSleepDuration / totalDuration;
+
+        if (ratio >= 0.50 && ratio <= 0.60) {
+            return 100;
+        } else if (ratio >= 0.40 && ratio < 0.50) {
+            return 80;
+        } else if (ratio > 0.60 && ratio <= 0.70) {
+            return 85;
+        } else if (ratio >= 0.30 && ratio < 0.40) {
+            return 60;
+        } else if (ratio > 0.70 && ratio <= 0.80) {
+            return 70;
+        } else {
+            return 40;
+        }
+    }
+
+    /**
+     * 清醒评分(满分100分)
+     * 评估清醒时长和清醒次数
+     */
+    private static int calculateAwakeScore(long awakeDuration, int awakeCount, long totalDuration) {
+        if (totalDuration <= 0) {
+            return 0;
+        }
+
+        double awakeRatio = (double) awakeDuration / totalDuration;
+
+        // 清醒时长评分
+        int durationScore;
+        if (awakeRatio <= 0.05) {
+            durationScore = 100;
+        } else if (awakeRatio <= 0.10) {
+            durationScore = 80;
+        } else if (awakeRatio <= 0.15) {
+            durationScore = 60;
+        } else if (awakeRatio <= 0.20) {
+            durationScore = 40;
+        } else {
+            durationScore = 20;
+        }
+
+        // 清醒次数评分
+        int countScore;
+        if (awakeCount <= 2) {
+            countScore = 100;
+        } else if (awakeCount <= 4) {
+            countScore = 80;
+        } else if (awakeCount <= 6) {
+            countScore = 60;
+        } else if (awakeCount <= 8) {
+            countScore = 40;
+        } else {
+            countScore = 20;
+        }
+
+        return (int)(durationScore * 0.6 + countScore * 0.4);
+    }
+
+    /**
+     * 获取睡眠状态评估结果
+     * @param startTime 开始时间
+     * @param endTime 结束时间
+     * @param deviceId 设备ID
+     * @return 睡眠状态描述
+     */
+    public String getSleepStatus(Date startTime, Date endTime, String deviceId
+                                 ) {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        // 构造日期列表
+        List<String> dateList = new ArrayList<>();
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(startTime);
+        while (!calendar.getTime().after(endTime)) {
+            dateList.add(sdf.format(calendar.getTime()));
+            calendar.add(Calendar.DATE, 1);
+        }
+
+        int taskCount = dateList.size();
+        ExecutorCompletionService<WatchSleepStatusEnum> completionService =
+                new ExecutorCompletionService<>(threadPoolTaskExecutor);
+
+        // 提交任务
+        for (String date : dateList) {
+            completionService.submit(() -> {
+                AppWatchSleepDataVo sleepVo = queryByDateAndDeviceIdAndState(date, deviceId);
+                return getSleepEnum(sleepVo);
+            });
+        }
+
+        try {
+            for (int i = 0; i < taskCount; i++) {
+                Future<WatchSleepStatusEnum> future = completionService.take();
+                WatchSleepStatusEnum result = future.get();
+                if (!WatchSleepStatusEnum.NORMAL.equals(result)) {
+                    return result.getDesc();
+                }
+            }
+        } catch (Exception e) {
+            log.error("判断睡眠状态异常:{}", e.getMessage(), e);
+        }
+        return WatchSleepStatusEnum.NORMAL.getDesc();
+    }
+
+    /**
+     * 根据日期和设备ID查询睡眠数据
+     * @param date 日期(yyyy-MM-dd格式)
+     * @param deviceId 设备ID
+     * @return 睡眠数据VO
+     */
+    private AppWatchSleepDataVo queryByDateAndDeviceIdAndState(String date, String deviceId) {
+        try {
+            // 解析日期范围
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+            Date startDate = sdf.parse(date);
+            Date endDate = DateUtils.addMilliseconds(
+                    DateUtils.addDays(startDate, 1),
+                    -1
+            );
+
+            // 查询当天的所有睡眠记录
+            List<FsThirdDeviceData> sleepRecords = sleepDataMapper.selectListByDateAndDeviceIdAndRecordType(
+                    startDate, endDate, deviceId, 7, null);
+
+            if (sleepRecords == null || sleepRecords.isEmpty()) {
+                return null;
+            }
+
+            // 计算详细统计信息
+            SleepStatistics statistics = calculateDetailedStatistics(sleepRecords);
+
+            // 转换为 AppWatchSleepDataVo
+            AppWatchSleepDataVo sleepVo = new AppWatchSleepDataVo();
+
+            // 总睡眠时间(分钟)
+            if (statistics.getTotalSleepHours() != null) {
+                sleepVo.setSleepTime((int) (statistics.getTotalSleepHours() * 60));
+            }
+
+            // 深睡时间(分钟)
+            if (statistics.getDeepSleepHours() != null) {
+                sleepVo.setDeepSleep((int) (statistics.getDeepSleepHours() * 60));
+            }
+
+            // 浅睡时间(分钟)
+            if (statistics.getLightSleepHours() != null) {
+                sleepVo.setLightSleep((int) (statistics.getLightSleepHours() * 60));
+            }
+
+            // 清醒次数
+            sleepVo.setWeakTime(statistics.getAwakeCount());
+
+            // 夜间睡眠次数(深睡次数 + 浅睡次数)
+            sleepVo.setSleepCount(statistics.getDeepSleepCount() + statistics.getLightSleepCount());
+
+            // 深睡比例(百分比)
+            if (statistics.getDeepSleepRatio() != null) {
+                sleepVo.setDeepScale((int) (statistics.getDeepSleepRatio() * 100));
+            }
+
+            // 浅睡比例(百分比)
+            if (statistics.getLightSleepRatio() != null) {
+                sleepVo.setLightScale((int) (statistics.getLightSleepRatio() * 100));
+            }
+
+            // 快速眼动比例(百分比)
+            if (statistics.getRemRatio() != null) {
+                sleepVo.setEyemoveScale((int) (statistics.getRemRatio() * 100));
+            }
+
+            return sleepVo;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 根据睡眠数据获取睡眠状态枚举
+     * @param sleepVo 睡眠数据VO
+     * @return 睡眠状态枚举
+     */
+    private WatchSleepStatusEnum getSleepEnum(AppWatchSleepDataVo sleepVo) {
+        WatchSleepStatusEnum sleepEnum = WatchSleepStatusEnum.NORMAL;
+        if (sleepVo != null) {
+            Integer sleepTime = sleepVo.getSleepTime();  // 总睡眠时间(分钟)
+            Integer deepSleep = sleepVo.getDeepSleep(); // 深睡时间(分钟)
+
+            if (sleepTime != null && sleepTime > 0) {
+                // 睡眠剥夺:总睡眠时间少于5小时(300分钟)
+                if (sleepTime < 300) {
+                    return WatchSleepStatusEnum.DEPRIVATION;
+                }
+                // OSA高风险:深睡比例低于15%
+                if (deepSleep != null) {
+                    double deepSleepRatio = (double) deepSleep / sleepTime;
+                    if (deepSleepRatio < 0.15) {
+                        return WatchSleepStatusEnum.OSA;
+                    }
+                }
+            }
+        }
+        return sleepEnum;
+    }
+
+    /**
+     * 批量获取多日睡眠状态(用于趋势分析)
+     * @param startTime 开始时间
+     * @param endTime 结束时间
+     * @param deviceId 设备ID
+     * @return 每日睡眠状态列表
+     */
+    public List<DailySleepStatusVo> getDailySleepStatusList(Date startTime, Date endTime,
+                                                            String deviceId) {
+        List<DailySleepStatusVo> resultList = new ArrayList<>();
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(startTime);
+
+        while (!calendar.getTime().after(endTime)) {
+            String dateStr = sdf.format(calendar.getTime());
+            DailySleepStatusVo dailyStatus = new DailySleepStatusVo();
+            dailyStatus.setDate(dateStr);
+
+            try {
+                AppWatchSleepDataVo sleepVo = queryByDateAndDeviceIdAndState(dateStr, deviceId);
+                WatchSleepStatusEnum statusEnum = getSleepEnum(sleepVo);
+                dailyStatus.setStatus(statusEnum.getDesc());
+                dailyStatus.setStatusValue(statusEnum.getValue());
+
+                if (sleepVo != null) {
+                    dailyStatus.setSleepTime(sleepVo.getSleepTime());
+                    dailyStatus.setDeepSleep(sleepVo.getDeepSleep());
+                    dailyStatus.setDeepScale(sleepVo.getDeepScale());
+                }
+            } catch (Exception e) {
+                log.error("查询日期 {} 睡眠状态异常:{}", dateStr, e.getMessage());
+                dailyStatus.setStatus("查询失败");
+            }
+
+            resultList.add(dailyStatus);
+            calendar.add(Calendar.DATE, 1);
+        }
+
+        return resultList;
+    }
+}

+ 4 - 0
fs-service/src/main/java/com/fs/watch/domain/DeviceFamily.java

@@ -8,6 +8,10 @@ public class DeviceFamily {
     private String name;
     //设备id
     private String deviceId;
+    //小护士设备
+    private String xhsDeviceId;
+    //小护士手表
+    private String newXhsDeviceId;
     //关系
     private String relationship;
 }

+ 0 - 83
fs-service/src/main/java/com/fs/watch/domain/FsMonitorDataType.java

@@ -1,83 +0,0 @@
-package com.fs.watch.domain;
-
-import com.fs.common.annotation.Excel;
-import com.fs.common.core.domain.BaseEntity;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
-
-/**
- * app-健康监测数据类型对象 fs_monitor_data_type
- *
- * @author fs
- * @date 2024-08-26
- */
-public class FsMonitorDataType extends BaseEntity
-{
-    private static final long serialVersionUID = 1L;
-
-    /** id */
-    private String id;
-
-    /** 数据类型 */
-    @Excel(name = "数据类型")
-    private String type;
-
-    /** 小标题 */
-    @Excel(name = "小标题")
-    private String title;
-
-    /** 图标 */
-    @Excel(name = "图标")
-    private String icon;
-
-    public void setId(String id)
-    {
-        this.id = id;
-    }
-
-    public String getId()
-    {
-        return id;
-    }
-    public void setType(String type)
-    {
-        this.type = type;
-    }
-
-    public String getType()
-    {
-        return type;
-    }
-    public void setTitle(String title)
-    {
-        this.title = title;
-    }
-
-    public String getTitle()
-    {
-        return title;
-    }
-    public void setIcon(String icon)
-    {
-        this.icon = icon;
-    }
-
-    public String getIcon()
-    {
-        return icon;
-    }
-
-    @Override
-    public String toString() {
-        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
-            .append("id", getId())
-            .append("type", getType())
-            .append("title", getTitle())
-            .append("icon", getIcon())
-            .append("createTime", getCreateTime())
-            .append("createBy", getCreateBy())
-            .append("updateTime", getUpdateTime())
-            .append("updateBy", getUpdateBy())
-            .toString();
-    }
-}

+ 68 - 0
fs-service/src/main/java/com/fs/watch/domain/SleepStatistics.java

@@ -0,0 +1,68 @@
+package com.fs.watch.domain;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 睡眠统计信息
+ */
+@Data
+public class SleepStatistics {
+    /** 总睡眠时长(小时) */
+    private Double totalSleepHours;
+
+    /** 总睡眠时长(毫秒) */
+    private Long totalDuration;
+
+    /** 深睡时长(小时) */
+    private Double deepSleepHours;
+
+    /** 深睡时长(毫秒) */
+    private Long deepSleepDuration;
+
+    /** 深睡次数 */
+    private Integer deepSleepCount;
+
+    /** 浅睡时长(小时) */
+    private Double lightSleepHours;
+
+    /** 浅睡时长(毫秒) */
+    private Long lightSleepDuration;
+
+    /** 浅睡次数 */
+    private Integer lightSleepCount;
+
+    /** 清醒时长(小时) */
+    private Double awakeHours;
+
+    /** 清醒时长(毫秒) */
+    private Long awakeDuration;
+
+    /** 清醒次数 */
+    private Integer awakeCount;
+
+    /** 快速眼动时长(小时) */
+    private Double remHours;
+
+    /** 快速眼动时长(毫秒) */
+    private Long remDuration;
+
+    /** 快速眼动次数 */
+    private Integer remCount;
+
+    /** 深睡比例(0-1) */
+    private Double deepSleepRatio;
+
+    /** 浅睡比例(0-1) */
+    private Double lightSleepRatio;
+
+    /** 清醒比例(0-1) */
+    private Double awakeRatio;
+
+    /** 快速眼动比例(0-1) */
+    private Double remRatio;
+
+    /** 睡眠区间列表(用于图表展示) */
+    private List<SleepSection> sleepSection;
+}

+ 96 - 0
fs-service/src/main/java/com/fs/watch/domain/WatchAudioMsgLog.java

@@ -0,0 +1,96 @@
+package com.fs.watch.domain;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+import java.util.UUID;
+
+/**
+* 语音聊天记录
+* @TableName watch_audio_msg_log
+*/
+public class WatchAudioMsgLog implements Serializable {
+
+    /**
+    * 主键id
+    */
+    private UUID id;
+    /**
+    * 设备编号
+    */
+    @ApiModelProperty("设备编号")
+    private String deviceId;
+
+    @ApiModelProperty("文件地址")
+    private String fileUrl;
+
+    @ApiModelProperty("0:发送 1:接收")
+    private Integer type;
+
+    @ApiModelProperty("结果 0:失败 1:成功")
+    private Integer status;
+
+    @ApiModelProperty("返回信息")
+    private String msg;
+
+    @ApiModelProperty("创建时间")
+    private String createTime;
+
+    public String getFileUrl() {
+        return fileUrl;
+    }
+
+    public void setFileUrl(String fileUrl) {
+        this.fileUrl = fileUrl;
+    }
+
+    public Integer getType() {
+        return type;
+    }
+
+    public void setType(Integer type) {
+        this.type = type;
+    }
+
+    public Integer getStatus() {
+        return status;
+    }
+
+    public void setStatus(Integer status) {
+        this.status = status;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public String getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(String createTime) {
+        this.createTime = createTime;
+    }
+
+    public UUID getId() {
+        return id;
+    }
+
+    public void setId(UUID id) {
+        this.id = id;
+    }
+
+    public String getDeviceId() {
+        return deviceId;
+    }
+
+    public void setDeviceId(String deviceId) {
+        this.deviceId = deviceId;
+    }
+
+
+}

+ 0 - 108
fs-service/src/main/java/com/fs/watch/domain/WatchDeviceBeginnerGuide.java

@@ -1,108 +0,0 @@
-package com.fs.watch.domain;
-
-import com.fs.common.annotation.Excel;
-import com.fs.common.core.domain.BaseEntity;
-import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
-
-/**
- * 新手引导对象 device_beginner_uide
- *
- * @author fs
- * @date 2024-09-06
- */
-public class WatchDeviceBeginnerGuide extends BaseEntity
-{
-    private static final long serialVersionUID = 1L;
-
-    /** 主键id */
-    private Long id;
-
-    /** 标题 */
-    @Excel(name = "标题")
-    private String title;
-
-    /** 链接 */
-    @Excel(name = "链接")
-    private String url;
-
-    /** 资料类型 1:文章 2:视频 */
-    @Excel(name = "资料类型 1:文章 2:视频")
-    private Long type;
-
-    /** 是否已删除 */
-    @Excel(name = "是否已删除")
-    private Long isDel;
-
-    public String getBelong() {
-        return belong;
-    }
-
-    public void setBelong(String belong) {
-        this.belong = belong;
-    }
-
-    private String belong;
-
-    public void setId(Long id)
-    {
-        this.id = id;
-    }
-
-    public Long getId()
-    {
-        return id;
-    }
-    public void setTitle(String title)
-    {
-        this.title = title;
-    }
-
-    public String getTitle()
-    {
-        return title;
-    }
-    public void setUrl(String url)
-    {
-        this.url = url;
-    }
-
-    public String getUrl()
-    {
-        return url;
-    }
-    public void setType(Long type)
-    {
-        this.type = type;
-    }
-
-    public Long getType()
-    {
-        return type;
-    }
-    public void setIsDel(Long isDel)
-    {
-        this.isDel = isDel;
-    }
-
-    public Long getIsDel()
-    {
-        return isDel;
-    }
-
-    @Override
-    public String toString() {
-        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
-            .append("id", getId())
-            .append("title", getTitle())
-            .append("url", getUrl())
-            .append("type", getType())
-            .append("createBy", getCreateBy())
-            .append("createTime", getCreateTime())
-            .append("updateBy", getUpdateBy())
-            .append("updateTime", getUpdateTime())
-            .append("isDel", getIsDel())
-            .append("belong", getBelong())
-            .toString();
-    }
-}

+ 56 - 0
fs-service/src/main/java/com/fs/watch/domain/WatchDeviceWeek.java

@@ -0,0 +1,56 @@
+package com.fs.watch.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fs.common.core.domain.BaseEntity;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+* 每周健康周报汇总
+* @TableName watch_device_week
+*/
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("watch_device_week") // 确保表名正确
+public class WatchDeviceWeek extends BaseEntity {
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    /**
+    * 设备编号
+    */
+    @ApiModelProperty("设备编号")
+    private String deviceId;
+    /**
+    * 异常数据
+    */
+    @ApiModelProperty("异常数据")
+    private String listJson;
+    /**
+    * 标题
+    */
+    @ApiModelProperty("标题")
+    private String title;
+    /**
+    * 详细描述
+    */
+    @ApiModelProperty("详细描述")
+    private String desc;
+    /**
+    * 评分
+    */
+    @ApiModelProperty("评分")
+    private Integer score;
+    /**
+    *
+    */
+    private String aiSuggestion;
+
+    private Long userId;
+
+
+
+}

+ 6 - 0
fs-service/src/main/java/com/fs/watch/domain/WatchFsUser.java

@@ -177,4 +177,10 @@ public class WatchFsUser extends BaseEntity {
      */
     private String monitorDataTypeOrder;
 
+    //小护士设备id
+    private String xhsDeviceId;
+
+    //小护士手表设备id
+    private String newXhsDeviceId;
+
 }

+ 89 - 0
fs-service/src/main/java/com/fs/watch/domain/WatchSosCallLogs.java

@@ -0,0 +1,89 @@
+package com.fs.watch.domain;
+
+import java.io.Serializable;
+import java.util.UUID;
+
+/**
+ * sos报警日志(WatchSosCallLogs)实体类
+ *
+ * @author makejava
+ * @since 2024-12-24 14:30:26
+ */
+public class WatchSosCallLogs implements Serializable {
+    private static final long serialVersionUID = 656916219606367008L;
+/**
+     * 主键id
+     */
+    private UUID id;
+/**
+     * 设备编号
+     */
+    private String deviceId;
+/**
+     * 报警时间
+     */
+    private String alarmTime;
+/**
+     * sos时的定位 纬度
+     */
+    private String lat;
+/**
+     * sos时的定位 经度
+     */
+    private String lon;
+/**
+     * 通话日志json
+     */
+    private String callLogs;
+
+
+    public UUID getId() {
+        return id;
+    }
+
+    public void setId(UUID id) {
+        this.id = id;
+    }
+
+    public String getDeviceId() {
+        return deviceId;
+    }
+
+    public void setDeviceId(String deviceId) {
+        this.deviceId = deviceId;
+    }
+
+    public String getAlarmTime() {
+        return alarmTime;
+    }
+
+    public void setAlarmTime(String alarmTime) {
+        this.alarmTime = alarmTime;
+    }
+
+    public String getLat() {
+        return lat;
+    }
+
+    public void setLat(String lat) {
+        this.lat = lat;
+    }
+
+    public String getLon() {
+        return lon;
+    }
+
+    public void setLon(String lon) {
+        this.lon = lon;
+    }
+
+    public String getCallLogs() {
+        return callLogs;
+    }
+
+    public void setCallLogs(String callLogs) {
+        this.callLogs = callLogs;
+    }
+
+}
+

+ 25 - 0
fs-service/src/main/java/com/fs/watch/domain/WatchUser.java

@@ -87,6 +87,15 @@ public class WatchUser implements Serializable {
 
 
 
+    //小护士设备id
+    private String xhsDeviceId;
+
+
+    //小护士手表设备id
+    private String newXhsDeviceId;
+
+
+
     public String getTargetActivity() {
         return targetActivity;
     }
@@ -223,5 +232,21 @@ public class WatchUser implements Serializable {
     public void setNickName(String nickName) {
         this.nickName = nickName;
     }
+    public String getXhsDeviceId() {
+        return xhsDeviceId;
+    }
+
+    public void setXhsDeviceId(String xhsDeviceId) {
+        this.xhsDeviceId = xhsDeviceId;
+    }
+
+
+    public String getNewXhsDeviceId() {
+        return newXhsDeviceId;
+    }
+
+    public void setNewXhsDeviceId(String newXhsDeviceId) {
+        this.newXhsDeviceId = newXhsDeviceId;
+    }
 }
 

+ 4 - 0
fs-service/src/main/java/com/fs/watch/domain/vo/AppFsUserHealthReportVo.java

@@ -10,4 +10,8 @@ public class AppFsUserHealthReportVo {
     private String title; //标题
     private String desc; //详细描述
     private Integer score;//评分
+    private String aiSuggestion;
+    private Integer sessionId;
+    private Integer roleId = 140;
+
 }

+ 4 - 0
fs-service/src/main/java/com/fs/watch/domain/vo/AppFsUserHealthVo.java

@@ -20,5 +20,9 @@ public class AppFsUserHealthVo{
 
     //舌诊日期
     private List<String> tongueDateList;
+    //面诊日期
+    private List<String> pulseDateList;
+    //脉诊日期
+    private List<String> surfaceDateList;
 
 }

+ 7 - 0
fs-service/src/main/java/com/fs/watch/domain/vo/AppFsUserVo.java

@@ -119,4 +119,11 @@ public class AppFsUserVo {
     /** 微信公众号OPENID */
     @Excel(name = "微信公众号OPENID")
     private String mpOpenId;
+    /** 既往病史 */
+    @Excel(name = "既往病史")
+    private String previousMedicalHistory;
+
+    //小护士设备id
+    private String xhsDeviceId;
+
 }

+ 4 - 0
fs-service/src/main/java/com/fs/watch/domain/vo/AppWatchSleepDataVo.java

@@ -2,6 +2,8 @@ package com.fs.watch.domain.vo;
 
 import lombok.Data;
 
+import java.util.List;
+
 @Data
 public class AppWatchSleepDataVo extends WatchSleepDataVo {
     /**
@@ -39,4 +41,6 @@ public class AppWatchSleepDataVo extends WatchSleepDataVo {
      * 呼吸质量 得分(百分制)
      */
     private Integer breathScore;
+
+    private List<WatchSleepDataVo> watchSleepDataVoList;
 }

+ 27 - 0
fs-service/src/main/java/com/fs/watch/domain/vo/DailySleepStatusVo.java

@@ -0,0 +1,27 @@
+package com.fs.watch.domain.vo;
+
+import lombok.Data;
+
+/**
+ * 每日睡眠状态VO
+ */
+@Data
+public class DailySleepStatusVo {
+    /** 日期(yyyy-MM-dd) */
+    private String date;
+
+    /** 睡眠状态描述 */
+    private String status;
+
+    /** 睡眠状态值 */
+    private Integer statusValue;
+
+    /** 总睡眠时间(分钟) */
+    private Integer sleepTime;
+
+    /** 深睡时间(分钟) */
+    private Integer deepSleep;
+
+    /** 深睡比例(百分比) */
+    private Integer deepScale;
+}

+ 69 - 0
fs-service/src/main/java/com/fs/watch/domain/vo/WatchDeviceInfoAndIotExportVO.java

@@ -0,0 +1,69 @@
+package com.fs.watch.domain.vo;
+
+import com.fs.common.annotation.Excel;
+import lombok.Data;
+
+/**
+ * @author MixLiu
+ * @date 2025/11/18 下午1:44)
+ */
+
+@Data
+public class WatchDeviceInfoAndIotExportVO {
+
+
+
+    @Excel(name = "所属公司")
+    private String companyName;
+
+    @Excel(name = "设备编号")
+    private String deviceId;
+
+
+    @Excel(name = "ICCID")
+    private String iccid;
+
+    //物联网卡运营商类型:1=移动 2=联通 3=电信
+    private Integer operatorType;
+
+    @Excel(name = "运营商")
+    private String operatorTypeName;
+
+    //当前状态 5=已激活 6=已停用
+    private Integer status;
+
+    //当前状态 5=已激活 6=已停用
+    @Excel(name = "状态")
+    private String statusName;
+
+    //当月总流量,单位MB
+    @Excel(name = "当月总流量")
+    private Integer totalFlowSize;
+
+    //当月已使用流量,单位MB
+    @Excel(name = "当月已使用流量")
+    private Integer usedFlowSize;
+
+    //当前套餐名称
+    @Excel(name = "当前套餐")
+    private String currentPlanName;
+
+    //套餐开始时间
+    @Excel(name = "套餐开始时间")
+    private String currentPlanStartTime;
+
+    //套餐失效时间
+    @Excel(name = "套餐失效时间")
+    private String currentPlanExpireTime;
+
+    //下期套餐名称
+    @Excel(name = "下期套餐")
+    private String nextPlanName;
+
+    //实名状态 0 未认证  1 已认证 2人工审核中
+    private Integer certified;
+
+    //实名状态 0 未认证  1 已认证 2人工审核中
+    @Excel(name = "实名状态")
+    private String certifiedName;
+}

+ 0 - 9
fs-service/src/main/java/com/fs/watch/domain/vo/WatchDeviceInfoAndUserIdVo.java

@@ -1,9 +0,0 @@
-package com.fs.watch.domain.vo;
-
-import com.fs.watch.domain.WatchDeviceInfo;
-import lombok.Data;
-
-@Data
-public class WatchDeviceInfoAndUserIdVo extends WatchDeviceInfo {
-    private Long userId;
-}

+ 2 - 0
fs-service/src/main/java/com/fs/watch/domain/vo/WatchSleepDataVo.java

@@ -15,6 +15,8 @@ public class WatchSleepDataVo {
      */
     private String deviceId;
 
+    private String date; //时间
+
     /**
      * 开始时间
      */

+ 12 - 0
fs-service/src/main/java/com/fs/watch/domain/vo/WatchSportDataByDateAndThirdDeviceVo.java

@@ -0,0 +1,12 @@
+package com.fs.watch.domain.vo;
+
+import com.fs.watch.domain.WatchSportData;
+import lombok.Data;
+
+@Data
+public class WatchSportDataByDateAndThirdDeviceVo extends WatchSportData {
+    /**
+     * 时长(秒)
+     */
+    private Float duration;
+}

+ 10 - 0
fs-service/src/main/java/com/fs/watch/domain/vo/WatchSportRecordVo.java

@@ -23,4 +23,14 @@ public class WatchSportRecordVo {
      */
     private Float time;
 
+    /**
+     * 步数
+     */
+    private Long step;
+
+    /**
+     * 卡路里
+     */
+    private Float calorie;
+
 }

+ 2 - 0
fs-service/src/main/java/com/fs/watch/mapper/WatchAlarmDataMapper.java

@@ -36,4 +36,6 @@ public interface WatchAlarmDataMapper{
     Integer setAppStatusByDeviceId(@Param("deviceId")String deviceId);
 
     Boolean deleteByDeviceId(@Param("deviceId")String deviceId);
+
+    Integer setLocation(@Param("data")WatchAlarmData watchAlarmData);
 }

+ 12 - 0
fs-service/src/main/java/com/fs/watch/mapper/WatchAudioMsgLogMapper.java

@@ -0,0 +1,12 @@
+package com.fs.watch.mapper;
+
+import com.fs.common.annotation.DataSource;
+import com.fs.common.enums.DataSourceType;
+import com.fs.watch.domain.WatchAudioMsgLog;
+import org.apache.ibatis.annotations.Param;
+
+@DataSource(DataSourceType.CLICKHOUSE)
+public interface WatchAudioMsgLogMapper {
+
+    void insert(@Param("data") WatchAudioMsgLog data);
+}

+ 4 - 8
fs-service/src/main/java/com/fs/watch/mapper/WatchBloodPressureDataMapper.java

@@ -14,34 +14,30 @@ import java.util.Map;
 * @createDate 2024-10-15 11:06:50
 * @Entity watch.domain.WatchBloodPressureData
 */
+@DataSource(DataSourceType.CLICKHOUSE)
 public interface WatchBloodPressureDataMapper{
 
-    @DataSource(DataSourceType.CLICKHOUSE)
     void insert(@Param("data") WatchBloodPressureData data);
 
-    @DataSource(DataSourceType.CLICKHOUSE)
     Integer queryByCreateTime(@Param("createTime") String createTime);
 
-    @DataSource(DataSourceType.CLICKHOUSE)
     List<?> queryByDateAndDeviceId(@Param("date") String date, @Param("deviceId") String deviceId);
 
-    @DataSource(DataSourceType.CLICKHOUSE)
     List<WatchBloodPressureData> queryBpByDate(@Param("startTime") String startTime, @Param("endTime") String endTime,
                                                @Param("deviceId") String deviceId, @Param("status") Integer status);
 
-    @DataSource(DataSourceType.CLICKHOUSE)
+
     List<Map<String, Object>> countBpByDate(@Param("startTime") String startTime, @Param("endTime") String endTime, @Param("deviceId") String deviceId);
 
-    @DataSource(DataSourceType.CLICKHOUSE)
+    Map<String, Integer> countMaxAndMinBpByDate(@Param("startTime") String startTime, @Param("endTime") String endTime, @Param("deviceId") String deviceId);
+
     WatchBloodPressureData getLatest(@Param("deviceId") String deviceId);
 
-    @DataSource(DataSourceType.CLICKHOUSE)
     int countBpPageByDate(@Param("startTime") String startTime,
                           @Param("endTime") String endTime,
                           @Param("deviceId") String deviceId,
                           @Param("status") Integer status);
 
-    @DataSource(DataSourceType.CLICKHOUSE)
     List<WatchBloodPressureData> queryBgPageByDate(@Param("startTime") String startTime,
                                                    @Param("endTime") String endTime,
                                                    @Param("deviceId") String deviceId,

+ 2 - 0
fs-service/src/main/java/com/fs/watch/mapper/WatchDeviceInfoClicMapper.java

@@ -32,5 +32,7 @@ public interface WatchDeviceInfoClicMapper {
     List<WatchDeviceInfoClic> selectDeviceInfoList(WatchDeviceInfoClicParam param);
 
     WatchDeviceInfoClic selectOneByIcc(@Param("iccid")String iccid);
+
+    List<WatchDeviceInfoClic> selectListByIccList(@Param("iccidList") List<String> iccidList);
 }
 

+ 4 - 0
fs-service/src/main/java/com/fs/watch/mapper/WatchDeviceInfoMapper.java

@@ -69,4 +69,8 @@ public interface WatchDeviceInfoMapper{
     List<WatchDeviceInfo> selectListByUserOrFamilyUser(@Param("userId") Long userId);
 
     void removeUserId(WatchDeviceInfo data);
+
+    WatchDeviceInfo selectByUserId(String userId);
+
+    List<WatchDeviceInfoVo> selectCompanyNameByList(@Param("deviceIds") List<String> deviceIds);
 }

+ 68 - 0
fs-service/src/main/java/com/fs/watch/mapper/WatchDeviceWeekMapper.java

@@ -0,0 +1,68 @@
+package com.fs.watch.mapper;
+
+import com.fs.watch.domain.WatchDeviceWeek;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+* @author Administrator
+* @description 针对表【watch_device_week(每周健康周报汇总)】的数据库操作Mapper
+* @createDate 2025-10-11 13:22:54
+* @Entity generator.domain.WatchDeviceWeek
+*/
+public interface WatchDeviceWeekMapper {
+
+    /**
+     * 查询每周健康周报汇总
+     *
+     * @param id 每周健康周报汇总主键
+     * @return 每周健康周报汇总
+     */
+    WatchDeviceWeek selectWatchDeviceWeekById(Long id);
+
+    /**
+     * 查询每周健康周报汇总列表
+     *
+     * @param watchDeviceWeek 每周健康周报汇总
+     * @return 每周健康周报汇总集合
+     */
+    List<WatchDeviceWeek> selectWatchDeviceWeekList(WatchDeviceWeek watchDeviceWeek);
+
+    /**
+     * 新增每周健康周报汇总
+     *
+     * @param watchDeviceWeek 每周健康周报汇总
+     * @return 结果
+     */
+    int insertWatchDeviceWeek(WatchDeviceWeek watchDeviceWeek);
+
+    /**
+     * 修改每周健康周报汇总
+     *
+     * @param watchDeviceWeek 每周健康周报汇总
+     * @return 结果
+     */
+    int updateWatchDeviceWeek(WatchDeviceWeek watchDeviceWeek);
+
+    /**
+     * 删除每周健康周报汇总
+     *
+     * @param id 每周健康周报汇总主键
+     * @return 结果
+     */
+    int deleteWatchDeviceWeekById(Long id);
+
+    /**
+     * 批量删除每周健康周报汇总
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    int deleteWatchDeviceWeekByIds(Long[] ids);
+
+    WatchDeviceWeek getByDeviceIdAndTime(@Param("deviceId") String deviceId,@Param("createTime") Date createTime);
+
+    WatchDeviceWeek getByUserIdAndTime(@Param("userId") Long userId,@Param("createTime") Date createTime);
+}

+ 2 - 0
fs-service/src/main/java/com/fs/watch/mapper/WatchDoctorMapper.java

@@ -65,4 +65,6 @@ public interface WatchDoctorMapper extends BaseMapper<WatchDoctor>{
     void insertBatchWatchUserCompany(@Param("list") ArrayList<WatchDoctor> dList);
 
     void deleteBatch(@Param("deviceId")Long deviceId,@Param("list") List<String> subDoctorList);
+
+    WatchDoctor selectDoctorByDeviceId(Long deviceId);
 }

+ 2 - 0
fs-service/src/main/java/com/fs/watch/mapper/WatchHeartRateDataMapper.java

@@ -38,5 +38,7 @@ public interface WatchHeartRateDataMapper{
 
     List<Map<String, Object>> countBpByDate(@Param("startTime")String startTime, @Param("endTime") String endTime, @Param("deviceId")String deviceId);
 
+    Map<String, Integer> countMaxAndAvgBpByDate(@Param("startTime")String startTime, @Param("endTime") String endTime, @Param("deviceId")String deviceId);
+
     List<WatchHeartRateData> queryByMonth(@Param("deviceId")String deviceId, @Param("monthStr")String monthStr);
 }

+ 36 - 0
fs-service/src/main/java/com/fs/watch/mapper/WatchSosCallLogsMapper.java

@@ -0,0 +1,36 @@
+package com.fs.watch.mapper;
+
+import com.fs.common.annotation.DataSource;
+import com.fs.common.enums.DataSourceType;
+import com.fs.watch.domain.WatchSosCallLogs;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * sos报警日志(WatchSosCallLogs)表数据库访问层
+ *
+ * @author makejava
+ * @since 2024-12-24 14:30:26
+ */
+@DataSource(DataSourceType.CLICKHOUSE)
+public interface WatchSosCallLogsMapper {
+
+
+    /**
+     * 新增数据
+     *
+     * @param watchSosCallLogs 实例对象
+     * @return 影响行数
+     */
+    void insert(@Param("data")WatchSosCallLogs watchSosCallLogs);
+
+    Integer queryByAlarmTime(@Param("alarmTime")String alarmTime);
+
+    WatchSosCallLogs getByDeviceIdAndTime(@Param("deviceId") String deviceId, @Param("alarmTime") String alarmTime);
+
+    WatchSosCallLogs getByDeviceIdAndTimeOne(@Param("deviceId") String deviceId, @Param("alarmTime") long alarmTime);
+
+    void batchInsertData(@Param("list") List<WatchSosCallLogs> list);
+}
+

+ 2 - 0
fs-service/src/main/java/com/fs/watch/mapper/WatchSpo2DataMapper.java

@@ -40,4 +40,6 @@ public interface WatchSpo2DataMapper {
                                             @Param("num") Integer num,
                                             @Param("size") Integer size
     );
+
+    Float countAvgBpByDate(@Param("startTime") String startTime, @Param("endTime") String endTime, @Param("deviceId") String deviceId);
 }

+ 15 - 0
fs-service/src/main/java/com/fs/watch/param/DeviceSendParam.java

@@ -0,0 +1,15 @@
+package com.fs.watch.param;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+public class DeviceSendParam {
+    @NotNull
+    private String deviceId;
+    @NotNull
+    private String fileUrl;
+    @NotNull
+    private String sendUserName;
+}

+ 0 - 1
fs-service/src/main/java/com/fs/watch/param/WatchChartQueryParam.java

@@ -1,6 +1,5 @@
 package com.fs.watch.param;
 
-import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fs.common.core.domain.BaseEntity;
 import lombok.Data;
 

+ 15 - 0
fs-service/src/main/java/com/fs/watch/param/WatchDeviceInfoQueryParam.java

@@ -22,6 +22,16 @@ public class WatchDeviceInfoQueryParam extends BaseQueryParam{
      */
     private Long doctorId;
 
+    /**
+     * 绑定用户id
+     */
+    private String userId;
+
+    /**
+     * 绑定家人用户id
+     */
+    private String familyUserId;
+
     /**
      * 所属医生名字
      */
@@ -59,4 +69,9 @@ public class WatchDeviceInfoQueryParam extends BaseQueryParam{
      */
     private String watchUserName;
 
+    /**
+     * 健康状态
+     */
+    private Integer isNormal;
+
 }

+ 17 - 0
fs-service/src/main/java/com/fs/watch/param/WatchUserByDeviceIdParam.java

@@ -0,0 +1,17 @@
+package com.fs.watch.param;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class WatchUserByDeviceIdParam {
+    private List<WatchUserByDeviceIdTemp> params;
+    private Boolean isFamily;
+
+    @Data
+    public static class WatchUserByDeviceIdTemp {
+        private String deviceId;
+        private Integer deviceType;
+    }
+}

+ 8 - 0
fs-service/src/main/java/com/fs/watch/service/DeviceSetUpService.java

@@ -3,6 +3,7 @@ package com.fs.watch.service;
 import com.fs.common.core.domain.AjaxResult;
 import com.fs.watch.domain.*;
 import com.fs.watch.domain.vo.AlarmClockVos;
+import com.fs.watch.param.DeviceSendParam;
 
 public interface DeviceSetUpService {
     Boolean userinfo(UserInfo userInfo);
@@ -72,4 +73,11 @@ public interface DeviceSetUpService {
     Boolean temperatureUnit (String deviceNumber,Integer unit);
 
     DeviceUserInfo getUserinfo(String deviceId,Long userId,Integer selectType);
+
+    /**
+     * 发送语音给腕表
+     * @param param
+     * @return
+     */
+    Boolean sendMp3(DeviceSendParam param);
 }

+ 7 - 0
fs-service/src/main/java/com/fs/watch/service/WatchAudioMsgLogService.java

@@ -0,0 +1,7 @@
+package com.fs.watch.service;
+
+import com.fs.watch.domain.WatchAudioMsgLog;
+
+public interface WatchAudioMsgLogService {
+    Boolean insert(WatchAudioMsgLog data);
+}

+ 2 - 1
fs-service/src/main/java/com/fs/watch/service/WatchBasicInfoService.java

@@ -46,5 +46,6 @@ public interface WatchBasicInfoService{
 
     List<GnssVo> queryGnssByDate(String starTime, String endTime, String deviceId);
 
-    AppFsUserHealthReportVo getAppFsUserHealthReportVo(Date startTime, Date endTime, String deviceId);
+    AppFsUserHealthReportVo getAppFsUserHealthReportVo(Date startTime, Date endTime, String deviceId,Long watchUserId
+            ,Boolean isFamily,Integer isRefresh,Integer deviceType);
 }

+ 6 - 4
fs-service/src/main/java/com/fs/watch/service/WatchBloodGlucoseDataService.java

@@ -17,13 +17,15 @@ public interface WatchBloodGlucoseDataService{
 
     List<WatchBloodGlucoseData> queryByDateAndDeviceId(String date, String deviceId);
 
-    List<WatchBloodGlucoseData> queryBgByDate(Date startTime, Date endTime, String deviceId, Integer status);
+    List<WatchBloodGlucoseData> queryBgByDate(Date startTime, Date endTime, String deviceId, Integer status,Integer deviceType);
 
-    List<Map<String,Object>> countBgByDate(Date startTime, Date endTime, String deviceId);
+    List<Map<String,Object>> countBgByDate(Date startTime, Date endTime, String deviceId,Integer deviceType);
 
     WatchBloodGlucoseData getLatest(String deviceId);
 
-    int countBgPageByDate(Date startTime, Date endTime, String deviceId,Integer status);
+    int countBgPageByDate(Date startTime, Date endTime, String deviceId,Integer status,Integer deviceType);
 
-    List<WatchBloodGlucoseData> queryBgPageByDate(Date startTime, Date endTime, String deviceId, Integer status,Integer num, Integer size);
+    List<WatchBloodGlucoseData> queryBgPageByDate(Date startTime, Date endTime, String deviceId, Integer status,Integer num, Integer size,Integer deviceType);
+
+    Integer getStatus(Double num);
 }

+ 2 - 0
fs-service/src/main/java/com/fs/watch/service/WatchBloodPressureDataService.java

@@ -28,4 +28,6 @@ public interface WatchBloodPressureDataService{
     int countBpPageByDate(Date startTime, Date endTime, String deviceId, Integer status);
 
     List<WatchBloodPressureData> queryBgPageByDate(Date startTime, Date endTime, String deviceId, Integer status, Integer num, Integer size);
+
+    Integer getStatus(int sbp, int dbp);
 }

+ 4 - 3
fs-service/src/main/java/com/fs/watch/service/WatchDataService.java

@@ -5,13 +5,14 @@ import com.fs.watch.domain.vo.AppInfoVo;
 import com.fs.watch.domain.vo.FsMonitorDataVo;
 import com.fs.watch.domain.vo.QueryPageMonthVo;
 import com.fs.watch.domain.vo.WatchLastHealthDataVo;
+import com.fs.watch.param.WatchUserByDeviceIdParam;
 
 import java.util.List;
 
 public interface WatchDataService {
-    List<FsMonitorDataVo> queryIndexWatchData(List<String> types, String deviceId,String userId);
+    List<FsMonitorDataVo> queryIndexWatchData(List<String> types, String deviceId,String userId,Integer deviceType);
 
-    List<AppInfoVo> getUserByDeviceId(String deviceIds, Boolean isFamily,Long userId);
+    List<AppInfoVo> getUserByDeviceId(WatchUserByDeviceIdParam watchUserByDeviceIdParam, Long userId);
 
     Boolean power(String deviceId, Boolean isLcdgesture, Boolean isLocation, Boolean isPower, Boolean isHeartHealth);
 
@@ -21,7 +22,7 @@ public interface WatchDataService {
 
     Boolean setDeviceMode(String deviceId, Boolean isLocation, Integer interval, Boolean isPower);
 
-    QueryPageMonthVo queryMonthByDeviceId(String deviceId, Integer pageSize, Integer pageNum);
+    QueryPageMonthVo queryMonthByDeviceId(String deviceId, Integer pageSize, Integer pageNum,Integer deviceType);
 
     List<WatchLastHealthDataVo> queryLastWatchData(String deviceId);
 

+ 0 - 24
fs-service/src/main/java/com/fs/watch/service/WatchDeviceBeginnerGuideService.java

@@ -1,24 +0,0 @@
-package com.fs.watch.service;
-
-import com.fs.watch.domain.WatchDeviceBeginnerGuide;
-
-import java.util.List;
-
-public interface WatchDeviceBeginnerGuideService {
-    /**
-     * 查询新手引导
-     *
-     * @param id 新手引导主键
-     * @return 新手引导
-     */
-    public WatchDeviceBeginnerGuide selectDeviceBeginnerGuideById(Long id);
-
-    /**
-     * 查询新手引导列表
-     *
-     * @param deviceBeginnerGuide 新手引导
-     * @return 新手引导集合
-     */
-    public List<WatchDeviceBeginnerGuide> selectDeviceBeginnerGuideList(WatchDeviceBeginnerGuide deviceBeginnerGuide);
-
-}

+ 3 - 0
fs-service/src/main/java/com/fs/watch/service/WatchDeviceInfoClicService.java

@@ -2,6 +2,7 @@ package com.fs.watch.service;
 
 import com.fs.common.core.page.TableDataInfo;
 import com.fs.watch.domain.WatchDeviceInfoClic;
+import com.fs.watch.domain.vo.WatchDeviceInfoAndIotExportVO;
 import com.fs.watch.param.DeviceIdAndIotInfoQueryParam;
 import com.fs.watch.param.WatchDeviceInfoClicParam;
 
@@ -25,4 +26,6 @@ public interface WatchDeviceInfoClicService {
     TableDataInfo getDeviceIdAndIotInfo(DeviceIdAndIotInfoQueryParam param);
 
     List<WatchDeviceInfoClic> selectWatchDeviceInfoClicList(WatchDeviceInfoClicParam param);
+
+    List<WatchDeviceInfoAndIotExportVO> exportDeviceIdAndIotInfo(DeviceIdAndIotInfoQueryParam param);
 }

+ 2 - 0
fs-service/src/main/java/com/fs/watch/service/WatchDeviceInfoService.java

@@ -62,4 +62,6 @@ public interface WatchDeviceInfoService{
     void bindCompany(CompanyUserUser map);
 
     void removeUserId(String deviceId);
+
+    List<WatchDeviceInfoVo> selectCompanyNameByList(List<String> deviceIds);
 }

+ 11 - 0
fs-service/src/main/java/com/fs/watch/service/WatchDeviceWeekService.java

@@ -0,0 +1,11 @@
+package com.fs.watch.service;
+
+
+/**
+* @author Administrator
+* @description 针对表【watch_device_week(每周健康周报汇总)】的数据库操作Service
+* @createDate 2025-10-11 13:22:54
+*/
+public interface WatchDeviceWeekService {
+
+}

+ 4 - 2
fs-service/src/main/java/com/fs/watch/service/WatchHeartRateDataService.java

@@ -20,7 +20,7 @@ public interface WatchHeartRateDataService{
 
     WatchHeartRateDataVo queryByDate(String date, String deviceId);
 
-    WatchHeartRateDataVo list(Date startTime, Date endTime, String deviceId);
+    WatchHeartRateDataVo list(Date startTime, Date endTime, String deviceId, Integer deviceType);
 
     WatchHeartRateData getLatest(String deviceId);
 
@@ -29,5 +29,7 @@ public interface WatchHeartRateDataService{
     List<WatchHeartRateData> queryHeartPageByDate(Date startTime, Date endTime, String deviceId, Integer pageNum,
                                                   Integer pageSize);
 
-    List<Map<String, Object>> countHeartByDate(Date startTime, Date endTime, String deviceId);
+    List<Map<String, Object>> countHeartByDate(Date startTime, Date endTime, String deviceId,Integer deviceType);
+
+    Integer getStatus(int maxBpm, int minBpm);
 }

+ 1 - 1
fs-service/src/main/java/com/fs/watch/service/WatchSleepDataService.java

@@ -21,7 +21,7 @@ public interface WatchSleepDataService{
 
     AppWatchSleepDataVo queryByDateAndDeviceIdAndState(String date, String deviceId);
 
-    AppWatchSleepDataVo list(Date startTime, Date endTime, String deviceId);
+    AppWatchSleepDataVo list(Date startTime, Date endTime, String deviceId, Integer deviceType);
 
 
     WatchSleepData getLast(String deviceId);

+ 33 - 0
fs-service/src/main/java/com/fs/watch/service/WatchSosCallLogsService.java

@@ -0,0 +1,33 @@
+package com.fs.watch.service;
+
+
+import com.fs.watch.domain.WatchSosCallLogs;
+
+import java.util.List;
+
+/**
+ * sos报警日志(WatchSosCallLogs)表服务接口
+ *
+ * @author makejava
+ * @since 2024-12-24 14:30:26
+ */
+public interface WatchSosCallLogsService {
+
+
+    /**
+     * 新增数据
+     *
+     * @param watchSosCallLogs 实例对象
+     * @return 实例对象
+     */
+    Boolean insert(WatchSosCallLogs watchSosCallLogs);
+
+    /**
+     * 批量添加
+     * @param list
+     * @return
+     */
+    Boolean batchInsertData(List<WatchSosCallLogs> list);
+
+
+}

+ 2 - 2
fs-service/src/main/java/com/fs/watch/service/WatchSpo2DataService.java

@@ -19,11 +19,11 @@ public interface WatchSpo2DataService{
 
     List<WatchSpo2DataVo> queryByDateAndDeviceIdAndState(String date, String deviceId);
 
-    WatchSpo2DataQueryVo querySpByDate(Date startTime, Date endTime, String deviceId);
+    WatchSpo2DataQueryVo querySpByDate(Date startTime, Date endTime, String deviceId,Integer deviceType);
 
     Integer getStatus(int maxOxy, int minOxy);
 
-    List<Map<String,Object>> countSpByDate(Date startTime, Date endTime, String deviceId);
+    List<Map<String,Object>> countSpByDate(Date startTime, Date endTime, String deviceId,Integer deviceType);
 
     WatchSpo2DataVo getLatest(String deviceId);
 

+ 3 - 3
fs-service/src/main/java/com/fs/watch/service/WatchSportDataService.java

@@ -23,15 +23,15 @@ public interface WatchSportDataService{
 
     List<WatchSportListVo> queryPageByDataAndDeviceId(Date startTime, Date endTime, String deviceId,Integer pageSize, Integer pageNum);
 
-    List<WatchSportRecordVo> queryRecord(String deviceId);
+    List<WatchSportRecordVo> queryRecord(String deviceId,Integer deviceType);
 
-    WatchSportIndexVo sportData(String userId,String deviceId,Boolean isFamily);
+    WatchSportIndexVo sportData(String userId,String deviceId,Boolean isFamily,Integer deviceType);
 
     List<WatchSportDataByDateVo> sportDataByDate(Date startTime, Date endTime, String deviceId);
 
     WatchSportDetailDataVo dataByType(String deviceId, String type);
 
-    AppFsUserHealthVo getUserHealthInfoByDeviceId(String deviceId,Date startTime, Date endTime,Long userId);
+    AppFsUserHealthVo getUserHealthInfoByDeviceId(String deviceId,Date startTime, Date endTime,Long userId,Integer deviceType);
 
     WatchStepStatusEnum getWeekStatus(String deviceId, String startTime, String endTime);
 }

+ 4 - 4
fs-service/src/main/java/com/fs/watch/service/WatchThirdBpDataService.java

@@ -23,15 +23,15 @@ public interface WatchThirdBpDataService{
 
     List<WatchThirdBpData> queryByDateAndDeviceId(String date, String deviceId);
 
-    List<WatchThirdBpData> queryBpByDate(String startTime, String endTime, String deviceId, Integer status);
+    List<WatchThirdBpData> queryBpByDate(String startTime, String endTime, String deviceId, Integer status,Integer deviceType);
 
     WatchThirdBpData getLatest(String deviceId);
 
     Integer getStatus(int sbp, int dbp);
 
-    List<Map<String, Object>> countBpByDate(Date startTime, Date endTime, String deviceId);
+    List<Map<String, Object>> countBpByDate(Date startTime, Date endTime, String deviceId,Integer deviceType);
 
-    int countBpPageByDate(Date startTime, Date endTime, String deviceId, Integer status);
+    int countBpPageByDate(Date startTime, Date endTime, String deviceId, Integer status,Integer deviceType);
 
-    List<WatchThirdBpData> queryBgPageByDate(Date startTime, Date endTime, String deviceId, Integer status, Integer num, Integer size);
+    List<WatchThirdBpData> queryBgPageByDate(Date startTime, Date endTime, String deviceId, Integer status, Integer num, Integer size,Integer deviceType);
 }

+ 4 - 4
fs-service/src/main/java/com/fs/watch/service/WatchThirdUaDataService.java

@@ -22,12 +22,12 @@ public interface WatchThirdUaDataService{
 
     List<WatchThirdUaData> queryByDateAndDeviceId(String date, String deviceId);
 
-    List<WatchThirdUaData> list(Date startTime, Date endTime, String deviceId);
+    List<WatchThirdUaData> list(Date startTime, Date endTime, String deviceId,Integer deviceType);
 
-    List<Map<String, Object>> countUaByDate(Date startTime, Date endTime, String deviceId);
+    List<Map<String, Object>> countUaByDate(Date startTime, Date endTime, String deviceId,Integer deviceType);
 
     List<WatchThirdUaData> queryListByDate(Date startTime, Date endTime, String deviceId, Integer pageNum,
-                                                Integer pageSize,Integer status);
+                                                Integer pageSize,Integer status,Integer deviceType);
 
-    int countTotalDate(Date startTime, Date endTime, String deviceId,Integer status);
+    int countTotalDate(Date startTime, Date endTime, String deviceId,Integer status,Integer deviceType);
 }

+ 6 - 1
fs-service/src/main/java/com/fs/watch/service/WatchUserService.java

@@ -10,6 +10,7 @@ import com.fs.watch.domain.vo.WatchUserAndHealthVo;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
 
+import java.util.HashMap;
 import java.util.List;
 
 /**
@@ -40,7 +41,7 @@ public interface WatchUserService {
      * @param deviceId
      * @return
      */
-    AppFsUserVo getUserInfoByDeviceId(String deviceId,Boolean isFamily,Long watchUserId);
+    AppFsUserVo getUserInfoByDeviceId(String deviceId,Boolean isFamily,Long watchUserId,Integer deviceType);
 
     /**
      * 通过ID查询单条数据
@@ -95,4 +96,8 @@ public interface WatchUserService {
     List<WatchUserAndHealthVo> listByDeviceIdNotNull();
 
     FsHealthTongue getLastTongueByDeviceId(String deviceId);
+
+    R editXHSDevice(HashMap<String, String> param);
+
+    R removeXHSDevice(String userId, String xhsDeviceId,String newXhsDeviceId);
 }

+ 63 - 0
fs-service/src/main/java/com/fs/watch/service/impl/DeviceSetUpServiceImpl.java

@@ -11,8 +11,13 @@ import com.fs.his.utils.PhoneUtil;
 import com.fs.watch.domain.*;
 import com.fs.watch.domain.vo.AlarmClockObjectVo;
 import com.fs.watch.domain.vo.AlarmClockVos;
+import com.fs.watch.mapper.WatchAudioMsgLogMapper;
+import com.fs.watch.param.DeviceSendParam;
 import com.fs.watch.service.*;
+import com.fs.watch.utils.AudioConvertUtil;
+import com.fs.watch.utils.MD5Utils;
 import com.fs.watch.utils.MyHttpUtils;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -26,6 +31,7 @@ import java.time.format.DateTimeFormatter;
 import java.util.*;
 
 @Service
+@Slf4j
 public class DeviceSetUpServiceImpl implements DeviceSetUpService {
     private MyHttpUtils httpUtils = new MyHttpUtils();
     @Autowired
@@ -38,6 +44,8 @@ public class DeviceSetUpServiceImpl implements DeviceSetUpService {
     private WatchSendMsgSetService watchSendMsgSetService;
     @Autowired
     private WatchSendMsgLogService watchSendMsgLogService;
+    @Autowired
+    private WatchAudioMsgLogMapper watchAudioMsgLogMapper;
 
     /**
      * 下发用户设置到设备
@@ -1271,9 +1279,64 @@ public class DeviceSetUpServiceImpl implements DeviceSetUpService {
                 } else {
                     userInfo.setPhone(PhoneUtil.decryptPhone(phone));
                 }
+                //2025-8-8新增需求手机号码脱敏显示
+                if(StringUtils.isNotBlank(userInfo.getPhone())){
+                    userInfo.setPhone(userInfo.getPhone().replaceAll("(\\d{3})\\d{8}", "$1********"));
+                }
             }
             return userInfo;
         }
         return null;
     }
+
+    @Override
+    public Boolean sendMp3(DeviceSendParam param) {
+        Date nowDate = DateUtils.getNowDate();
+        String fileUrl = param.getFileUrl();
+        String sendUserName = param.getSendUserName();
+        String deviceId = param.getDeviceId();
+        try {
+            fileUrl = AudioConvertUtil.convertUploadAndClean(
+                    fileUrl,
+                    deviceId,
+                    DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",nowDate),
+                    "/tmp/audio/"
+            );
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+        JSONObject fileInfo = MD5Utils.getMd5AndSizeFromUrl(fileUrl);
+        Map<String, Object> map = new HashMap<>();
+        map.put("type",3);
+        map.put("device_id",deviceId);
+        map.put("url",fileUrl);
+        map.put("md5",fileInfo.getString("md5"));
+        map.put("size",Long.valueOf(fileInfo.getString("size")));
+        map.put("sender",sendUserName);
+        //取时间的 时:分
+        map.put("send_time", DateUtils.parseDateToStr("HH:mm",nowDate));
+        Map response = httpUtils.getPost("/entservice2/file/download", map);
+        WatchAudioMsgLog watchAudioMsgLog = new WatchAudioMsgLog();
+        watchAudioMsgLog.setDeviceId(deviceId);
+        watchAudioMsgLog.setFileUrl(param.getFileUrl());
+        watchAudioMsgLog.setType(0);
+        watchAudioMsgLog.setCreateTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",nowDate));
+        watchAudioMsgLog.setStatus(0);
+        watchAudioMsgLog.setMsg(JSON.toJSONString(response));
+        if (response != null){
+            String rrpcCode = response.get("RrpcCode").toString();
+            if ("SUCCESS".equals(rrpcCode) || "TIMEOUT".equals(rrpcCode)){
+                watchAudioMsgLog.setStatus(1);
+            }
+
+        }
+        //记录发送记录
+        try {
+            watchAudioMsgLogMapper.insert(watchAudioMsgLog);
+        } catch (Exception e) {
+            log.error("插入 watchAudioMsgLog 失败,参数: {}", watchAudioMsgLog, e); // 关键:打印完整异常
+            throw new RuntimeException(e);
+        }
+        return watchAudioMsgLog.getStatus()==1?true:false;
+    }
 }

+ 38 - 1
fs-service/src/main/java/com/fs/watch/service/impl/WatchAlarmDataServiceImpl.java

@@ -1,13 +1,19 @@
 package com.fs.watch.service.impl;
 
+import com.fs.common.utils.StringUtils;
 import com.fs.watch.domain.WatchAlarmData;
+import com.fs.watch.domain.WatchSosCallLogs;
 import com.fs.watch.domain.vo.AppWatchAlarmDataVo;
 import com.fs.watch.mapper.WatchAlarmDataMapper;
+import com.fs.watch.mapper.WatchSosCallLogsMapper;
 import com.fs.watch.service.WatchAlarmDataService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
 import java.util.List;
 
 /**
@@ -20,6 +26,8 @@ import java.util.List;
 public class WatchAlarmDataServiceImpl implements WatchAlarmDataService {
     @Autowired
     private WatchAlarmDataMapper mapper;
+    @Autowired
+    private WatchSosCallLogsMapper sosCallLogsMapper;
 
     /**
      * 单条插入
@@ -76,8 +84,37 @@ public class WatchAlarmDataServiceImpl implements WatchAlarmDataService {
     @Override
     public AppWatchAlarmDataVo queryPageByAppStatus(WatchAlarmData data) {
         AppWatchAlarmDataVo vo = new AppWatchAlarmDataVo();
-        vo.setData(mapper.queryPageByStatus(data));
+        List<WatchAlarmData> list = mapper.queryPageByStatus(data);
+        if (list != null && !list.isEmpty()) {
+            for (WatchAlarmData watchAlarmData : list) {
+                if (StringUtils.isBlank(watchAlarmData.getLocation())){
+                    //查询经纬度
+                    String dateTime = watchAlarmData.getDateTime();
+                    if (StringUtils.isNotBlank(dateTime)){
+                        long alarmTimeTs = LocalDateTime.parse(dateTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
+                                .toEpochSecond(ZoneOffset.ofHours(8));
+                        WatchSosCallLogs sosCallLogs = sosCallLogsMapper.getByDeviceIdAndTimeOne(watchAlarmData.getDeviceId(), alarmTimeTs);
+                        if (sosCallLogs != null){
+                            long logTime = LocalDateTime.parse(sosCallLogs.getAlarmTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
+                                    .toEpochSecond(ZoneOffset.ofHours(8));
+                            String location = sosCallLogs.getLat()+","+sosCallLogs.getLon();
+                            long abs = Math.abs(alarmTimeTs - logTime);
+                            if (abs <= 120) {
+                                // 时间差小于或等于2分钟
+                                watchAlarmData.setLocation(location);
+                                //更新alarm的地址
+                                mapper.setLocation(watchAlarmData);
+                            }
+
+                        }
+                    }
+
+                }
+            }
+        }
+        vo.setData(list);
         vo.setUnreadNum(mapper.getUnreadNum(data.getDeviceId()));
+
         return vo;
     }
 

+ 80 - 0
fs-service/src/main/java/com/fs/watch/service/impl/WatchAudioMsgLogServiceImpl.java

@@ -0,0 +1,80 @@
+package com.fs.watch.service.impl;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fs.fastgptApi.util.AudioUtils;
+import com.fs.im.dto.OpenImMsgDTO;
+import com.fs.im.service.OpenIMService;
+import com.fs.watch.domain.WatchAudioMsgLog;
+import com.fs.watch.domain.WatchDeviceInfo;
+import com.fs.watch.domain.WatchDoctor;
+import com.fs.watch.mapper.WatchAudioMsgLogMapper;
+import com.fs.watch.mapper.WatchDeviceInfoMapper;
+import com.fs.watch.mapper.WatchDoctorMapper;
+import com.fs.watch.service.WatchAudioMsgLogService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Service
+@Slf4j
+public class WatchAudioMsgLogServiceImpl implements WatchAudioMsgLogService {
+    @Autowired
+    private WatchAudioMsgLogMapper mapper;
+    @Autowired
+    private WatchDeviceInfoMapper watchDeviceInfoMapper;
+    @Autowired
+    private WatchDoctorMapper watchDoctorMapper;
+    @Autowired
+    private OpenIMService openIMService;
+    @Override
+    public Boolean insert(WatchAudioMsgLog data) {
+        try {
+            mapper.insert(data);
+            //查询用户信息
+            WatchDeviceInfo watchDeviceInfo = watchDeviceInfoMapper.selectByDeviceNumber(data.getDeviceId());
+            //查询医生
+            WatchDoctor watchDoctor = watchDoctorMapper.selectDoctorByDeviceId(watchDeviceInfo.getDeviceId());
+            if (watchDoctor!=null){
+                OpenImMsgDTO openImMsgDTO = new OpenImMsgDTO();
+                openImMsgDTO.setSendID("U"+watchDeviceInfo.getUserId());
+                openImMsgDTO.setRecvID("D"+watchDoctor.getDoctorId());
+                openImMsgDTO.setContentType(103);
+                openImMsgDTO.setSessionType(1);
+                OpenImMsgDTO.Content content = new OpenImMsgDTO.Content();
+                HashMap<String, Object> map = new HashMap<>();
+                map.put("uuid","");
+                map.put("soundPath","");
+                map.put("dataSize",0);
+                map.put("soundType","");
+                map.put("sourceUrl",data.getFileUrl());
+                Integer durations = AudioUtils.getDurations(data.getFileUrl());
+                map.put("duration",durations);
+                ObjectMapper mapper = new ObjectMapper();
+                String json = mapper.writeValueAsString(map);
+                content.setContent(json);
+                openImMsgDTO.setContent(content);
+                openIMService.openIMSendMsg(openImMsgDTO);
+            }
+        } catch (Exception e) {
+            log.error("===============watchAudioData:insert=========================={}", e.getMessage());
+            return false;
+        }
+        return true;
+    }
+
+
+    private Map<String, Object> getAudioMsgLogMap(WatchAudioMsgLog data) {
+        Map<String, Object> params = new HashMap<>();
+        params.put("id", data.getId());
+        params.put("deviceId", data.getDeviceId());
+        params.put("fileUrl", data.getFileUrl());
+        params.put("type", data.getType());
+        params.put("status", data.getStatus());
+        params.put("msg", data.getMsg());
+        params.put("createTime", data.getCreateTime());
+        return params;
+    }
+}

+ 640 - 31
fs-service/src/main/java/com/fs/watch/service/impl/WatchBasicInfoServiceImpl.java

@@ -1,14 +1,30 @@
 package com.fs.watch.service.impl;
 
+import com.alibaba.fastjson.JSON;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fs.aiChat.mapper.InterestAiChatSessionMapper;
+import com.fs.common.core.domain.R;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.StringUtils;
-import com.fs.watch.domain.WatchBasicInfo;
-import com.fs.watch.domain.WatchDeviceInfo;
-import com.fs.watch.domain.WatchHeartRateData;
-import com.fs.watch.domain.vo.AppFsUserHealthReportVo;
-import com.fs.watch.domain.vo.AppHealthReportVo;
-import com.fs.watch.domain.vo.GnssVo;
-import com.fs.watch.domain.vo.WatchSleepDataVo;
+import com.fs.fastgptApi.param.ChatParam;
+import com.fs.fastgptApi.result.ChatDetailTStreamFResult;
+import com.fs.fastgptApi.result.KnowledgeBaseResult;
+import com.fs.fastgptApi.service.ChatService;
+import com.fs.his.domain.FsThirdDeviceData;
+import com.fs.his.mapper.FsHealthPulseMapper;
+import com.fs.his.mapper.FsHealthSurfaceMapper;
+import com.fs.his.mapper.FsHealthTongueMapper;
+import com.fs.his.mapper.FsThirdDeviceDataMapper;
+import com.fs.his.param.FsHealthPulseListUParam;
+import com.fs.his.param.FsHealthSurfaceListUParam;
+import com.fs.his.param.FsHealthTongueListUParam;
+import com.fs.his.vo.FsHealthPulseListVO;
+import com.fs.his.vo.FsHealthSurfaceListVO;
+import com.fs.his.vo.FsHealthTongueListUVO;
+import com.fs.watch.calculation.SleepScoreCalculator;
+import com.fs.watch.domain.*;
+import com.fs.watch.domain.vo.*;
 import com.fs.watch.enums.*;
 import com.fs.watch.mapper.*;
 import com.fs.watch.param.WatchDataQueryParam;
@@ -16,11 +32,15 @@ import com.fs.watch.service.*;
 import lombok.extern.slf4j.Slf4j;
 import org.jetbrains.annotations.NotNull;
 import org.mybatis.spring.MyBatisSystemException;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
 import java.util.*;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
@@ -55,6 +75,26 @@ public class WatchBasicInfoServiceImpl implements WatchBasicInfoService {
     private WatchSportDataService watchSportDataService;
     @Autowired
     private WatchDeviceInfoMapper watchDeviceInfoMapper;
+    @Autowired
+    private ChatService chatService;
+    @Autowired
+    private WatchUserService userService;
+    @Autowired
+    private WatchSportDataMapper sportDataMapper;
+    @Autowired
+    private FsHealthTongueMapper fsHealthTongueMapper;
+    @Autowired
+    private WatchDeviceWeekMapper watchDeviceWeekMapper;
+    @Autowired
+    private FsHealthSurfaceMapper fsHealthSurfaceMapper;
+    @Autowired
+    private FsHealthPulseMapper fsHealthPulseMapper;
+    @Autowired
+    InterestAiChatSessionMapper interestAiChatSessionMapper;
+    @Autowired
+    private FsThirdDeviceDataMapper fsThirdDeviceDataMapper;
+    private static final ObjectMapper objectMapper = new ObjectMapper();
+
 
     /**
      * 新增数据
@@ -64,11 +104,6 @@ public class WatchBasicInfoServiceImpl implements WatchBasicInfoService {
      */
     @Override
     public Boolean insert(WatchBasicInfo watchBasicInfo) {
-        //判断创建时间是否唯一
-        Integer num = watchBasicInfoMapper.queryByCreateTime(watchBasicInfo.getCreateTime());
-        if (num != null && num > 0) {
-            return false;
-        }
         try {
             watchBasicInfoMapper.insert(watchBasicInfo);
             //更新mysql的腕表数据
@@ -196,6 +231,9 @@ public class WatchBasicInfoServiceImpl implements WatchBasicInfoService {
         return gnssVos;
     }
 
+    private static final String APPKEY = "mygpt-nJvzjw0r7aEcvSA8po2BdHbUhm4oy8MEmK2V3r4YDHduo6gCJYWp";
+    private static final String AIURL = "http://154.8.194.176:3000/api";
+
     /**
      * >3个异常 只给出3个异常,优先级顺序 血糖、血压、心率、尿酸、血氧、睡眠、体温、步数
      *
@@ -205,28 +243,132 @@ public class WatchBasicInfoServiceImpl implements WatchBasicInfoService {
      * @return
      */
     @Override
-    public AppFsUserHealthReportVo getAppFsUserHealthReportVo(Date startTime, Date endTime, String deviceId) {
+    public AppFsUserHealthReportVo getAppFsUserHealthReportVo(Date startTime, Date endTime, String deviceId,
+                                                              Long watchUserId,
+                                                              Boolean isFamily,
+                                                              Integer isRefresh,
+                                                              Integer deviceType) {
         AppFsUserHealthReportVo res = new AppFsUserHealthReportVo();
+        //查询用户和指定ai医生的会话
+        Integer sessionId = interestAiChatSessionMapper.selectSessionIdByUserAndRole(watchUserId, 140);
+        res.setRoleId(140);
+        if (sessionId != null){
+            res.setSessionId(sessionId);
+        }
+        //1.查询是否存在结果
+        WatchDeviceWeek weekData;
+        if (StringUtils.isBlank(deviceId)) {
+            if (watchUserId == null) {
+                return res;
+            }
+            weekData = watchDeviceWeekMapper.getByUserIdAndTime(watchUserId, startTime);
+        } else {
+            weekData = watchDeviceWeekMapper.getByDeviceIdAndTime(deviceId, startTime);
+        }
+        if (weekData != null ) {
+            if (endTime.before(DateUtils.getNowDate()) || (isRefresh == null || isRefresh == 0)){
+                BeanUtils.copyProperties(weekData, res);
+                String listJson = weekData.getListJson();
+                if (StringUtils.isNotBlank(listJson)) {
+                    res.setList(JSON.parseArray(listJson, AppHealthReportVo.class));
+                }
+                return res;
+            }
+        }
+        //获取ai解析
+        CompletableFuture<Void> aiSuggestionFuture = CompletableFuture.runAsync(() -> {
+            getAiSuggestion(startTime, endTime, deviceId, watchUserId, isFamily, res,deviceType);
+        });
+        CompletableFuture<Void> totalScoreFuture = null;
+        if (StringUtils.isNotBlank(deviceId) && (deviceType == null || deviceType == 0)) {
+            //获取异常数据及分析
+            totalScoreFuture = CompletableFuture.runAsync(() -> {
+                getTotalScoreAndNormalData(startTime, endTime, deviceId, res);
+            });
+        }
+        try {
+            if (totalScoreFuture != null){
+                // 设置超时时间为30秒
+                CompletableFuture.allOf(aiSuggestionFuture, totalScoreFuture)
+                        .get(360, TimeUnit.SECONDS);
+            } else {
+                // 设置超时时间为30秒
+                CompletableFuture.allOf(aiSuggestionFuture)
+                        .get(360, TimeUnit.SECONDS);
+            }
+
+        } catch (TimeoutException e) {
+            // 超时处理
+            throw new RuntimeException("处理超时", e);
+        } catch (Exception e) {
+            throw new RuntimeException("异步执行失败", e);
+        }
+        //存到每周数据表
+        saveWeekData(startTime,endTime, deviceId, watchUserId,res);
+        return res;
+    }
+
+    /**
+     * 存到每周数据表
+     *
+     * @param startTime
+     * @param res
+     */
+    private void saveWeekData(Date startTime, Date endTime,String deviceId, Long userId, AppFsUserHealthReportVo res) {
+        //判断最后一天是否晚于当前时间
+//        if (!endTime.after(DateUtils.getNowDate())){
+            //否
+            if (StringUtils.isNotBlank(res.getAiSuggestion()) || res.getScore() != null) {
+                WatchDeviceWeek watchDeviceWeek = new WatchDeviceWeek();
+                BeanUtils.copyProperties(res, watchDeviceWeek);
+                List<AppHealthReportVo> list = res.getList();
+                if (list != null && !list.isEmpty()) {
+                    watchDeviceWeek.setListJson(JSON.toJSONString(list));
+                }
+                watchDeviceWeek.setCreateTime(startTime);
+                WatchDeviceWeek oldWeekData = null;
+                if (StringUtils.isNotBlank(deviceId)) {
+                    watchDeviceWeek.setDeviceId(deviceId);
+                    oldWeekData = watchDeviceWeekMapper.getByDeviceIdAndTime(deviceId, startTime);
+
+                } else {
+                    watchDeviceWeek.setDeviceId(userId.toString());
+                    oldWeekData = watchDeviceWeekMapper.getByUserIdAndTime(userId, startTime);
+                }
+                watchDeviceWeek.setUserId(userId);
+                //查询是否存在 存在更新
+                if (oldWeekData != null && oldWeekData.getId() != null) {
+                    watchDeviceWeek.setId(oldWeekData.getId());
+                    watchDeviceWeekMapper.updateWatchDeviceWeek(watchDeviceWeek);
+                } else {
+                    watchDeviceWeekMapper.insertWatchDeviceWeek(watchDeviceWeek);
+                }
+            }
+//        }
+
+    }
+
+    private void getTotalScoreAndNormalData(Date startTime, Date endTime, String deviceId, AppFsUserHealthReportVo res) {
         ArrayList<AppHealthReportVo> vos = new ArrayList<>();
         AtomicInteger score = new AtomicInteger(100); //分数
         String start = DateUtils.parseDateToStr("yyyy-MM-dd hh:mm:ss", startTime);
         String end = DateUtils.parseDateToStr("yyyy-MM-dd hh:mm:ss", endTime);
         //先查询睡眠数据
-        watchSleepDataService.getSleepStatus(startTime,endTime,deviceId);
+        watchSleepDataService.getSleepStatus(startTime, endTime, deviceId);
 
         // 顺序执行各项异常处理(最多保留3个)
-        getHealth(watchBloodGlucoseDataMapper.countBpByDate(start, end, deviceId), vos, WatchBgStatusEnum.class,score);
-        getHealth(watchBloodPressureDataMapper.countBpByDate(start, end, deviceId), vos, WatchBpStatusEnum.class,score);
-        getHealth(watchHeartRateDataMapper.countBpByDate(start, end, deviceId), vos, WatchHrStatusEnum.class,score);
-        getHealth(watchThirdUaDataMapper.countUaByDate(start, end, deviceId), vos, WatchUaStatusEnum.class,score);
-        getHealth(watchSpo2DataMapper.countSpByDate(start, end, deviceId), vos, WatchSpo2StatusEnum.class,score);
-        getHealth(watchSleepDataService.countSlByDate(start, end, deviceId), vos, WatchSleepStatusEnum.class,score);
-        getHealth(watchTemperatureDataMapper.countByDate(start, end, deviceId), vos, WatchTemperatureStatusEnum.class,score);
+        getHealth(watchBloodGlucoseDataMapper.countBpByDate(start, end, deviceId), vos, WatchBgStatusEnum.class, score);
+        getHealth(watchBloodPressureDataMapper.countBpByDate(start, end, deviceId), vos, WatchBpStatusEnum.class, score);
+        getHealth(watchHeartRateDataMapper.countBpByDate(start, end, deviceId), vos, WatchHrStatusEnum.class, score);
+        getHealth(watchThirdUaDataMapper.countUaByDate(start, end, deviceId), vos, WatchUaStatusEnum.class, score);
+        getHealth(watchSpo2DataMapper.countSpByDate(start, end, deviceId), vos, WatchSpo2StatusEnum.class, score);
+        getHealth(watchSleepDataService.countSlByDate(start, end, deviceId), vos, WatchSleepStatusEnum.class, score);
+        getHealth(watchTemperatureDataMapper.countByDate(start, end, deviceId), vos, WatchTemperatureStatusEnum.class, score);
 
 
         // 2. 步数(枚举可能不需要,可直接判断)
         WatchStepStatusEnum weekStatus = watchSportDataService.getWeekStatus(start, end, deviceId);
-        if (!Objects.equals(weekStatus.getValue(), WatchStepStatusEnum.NORMAL.getValue())){
+        if (!Objects.equals(weekStatus.getValue(), WatchStepStatusEnum.NORMAL.getValue())) {
             AppHealthReportVo vo = new AppHealthReportVo();
             vo.setPrediction(weekStatus.getPrediction());
             vo.setAnalysis(weekStatus.getAnalysis());
@@ -250,29 +392,496 @@ public class WatchBasicInfoServiceImpl implements WatchBasicInfoService {
         res.setScore(finalScore);
 
         WatchHealthEnum healthEnum = null;
-        if(finalScore>=90){
+        if (finalScore >= 90) {
             healthEnum = WatchHealthEnum.EXCELLENT;
-        } else if (finalScore>=80){
+        } else if (finalScore >= 80) {
             healthEnum = WatchHealthEnum.GOOD;
-        } else if (finalScore>=70){
+        } else if (finalScore >= 70) {
             healthEnum = WatchHealthEnum.GENERAL;
-        } else{
+        } else {
             healthEnum = WatchHealthEnum.POOR;
         }
         res.setTitle(healthEnum.getTitle());
         res.setDesc(healthEnum.getDesc());
+    }
 
-        return res;
+
+    /**
+     *
+     * @param startTime
+     * @param endTime
+     * @param deviceId
+     * @param watchUserId
+     * @param isFamily
+     * @param res
+     * @param deviceType 0腕表1小护士2新表
+     */
+    private void getAiSuggestion(Date startTime, Date endTime, String deviceId, Long watchUserId, Boolean isFamily,
+                                 AppFsUserHealthReportVo res,Integer deviceType) {
+        String aiSuggestion = "";
+        ChatParam param = new ChatParam();
+        param.setStream(false);
+        param.setDetail(true);
+        ChatParam.Variables variables = new ChatParam.Variables();
+        variables.setName("healthReport");
+        List<ChatParam.Message> messageList = new ArrayList<ChatParam.Message>();
+        param.setMessages(messageList);
+        ChatParam.Message message1 = new ChatParam.Message();
+        message1.setRole("user");
+        //组合询问问题
+        StringBuilder str = new StringBuilder();
+        str.append("今日日期:");
+        str.append(DateUtils.dateTimeNow("MM月dd日"));
+        //1.身高体重
+        if (watchUserId != null) {
+            AppFsUserVo userVo = userService.getUserInfoByDeviceId(deviceId, isFamily, watchUserId,deviceType);
+            if (userVo != null && userVo.getHeight() != null && userVo.getWeight() != null) {
+                str.append("【身高 ").append(userVo.getHeight()).append("cm 体重 ").append(userVo.getWeight()).append("kg】");
+            }
+        }
+        //按天查询总数
+        //创建日历实例用于遍历日期
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(startTime);
+
+        Calendar endCalendar = Calendar.getInstance();
+        endCalendar.setTime(endTime);
+        //遍历每一天
+        //运动
+        StringBuilder spotStr = new StringBuilder();
+        //血压
+        StringBuilder bpStr = new StringBuilder();
+        //血糖
+        StringBuilder bgStr = new StringBuilder();
+        //心率
+        StringBuilder hrStr = new StringBuilder();
+        //血氧
+        StringBuilder spo2Str = new StringBuilder();
+        //睡眠
+        StringBuilder sleepStr = new StringBuilder();
+        //舌诊
+        StringBuilder tongueStr = new StringBuilder();
+        //面诊
+        StringBuilder surfaceStr = new StringBuilder();
+        StringBuilder pulseStr = new StringBuilder();
+        //判断是否需要ai解析
+        Boolean isRequestAi = false;
+        while (!calendar.after(endCalendar)) {
+            Date currentStartDate = calendar.getTime();
+            String start = DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", currentStartDate);
+            String dateToStr = DateUtils.parseDateToStr("MM月dd日", currentStartDate);
+            //创建当天结束时间(23:59:59)
+            Calendar dayEndCalendar = (Calendar) calendar.clone();
+            dayEndCalendar.add(Calendar.DAY_OF_MONTH, 1);
+            dayEndCalendar.add(Calendar.SECOND, -1);
+            Date currentEndDate = dayEndCalendar.getTime();
+            String end = DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", currentEndDate);
+
+            if (StringUtils.isNotBlank(deviceId)) {
+                //2.计算每天步数总和
+                calculateStep(deviceId, start, end, spotStr, dateToStr,deviceType);
+                //3.血压
+                calculateBp(deviceId, start, end, bpStr, dateToStr,deviceType);
+
+
+                //4.血糖
+                calculateBg(deviceId, start, end, bgStr, dateToStr,deviceType);
+                //5.心率
+                calculateHr(deviceId, start, end, hrStr, dateToStr,deviceType);
+                //6.血氧
+                calculateSpo2(deviceId, start, end, spo2Str, dateToStr,deviceType);
+
+                //7.睡眠
+                calculateSleep(deviceId, DateUtils.parseDateToStr("yyyy-MM-dd", currentStartDate), sleepStr, dateToStr,deviceType);
+            }
+            if (watchUserId != null) {
+                //8.舌诊
+                calculateTongue(watchUserId, DateUtils.parseDateToStr("yyyy-MM-dd", currentStartDate), tongueStr, dateToStr);
+                //9.面诊
+                calculateSurface(watchUserId, DateUtils.parseDateToStr("yyyy-MM-dd", currentStartDate), surfaceStr, dateToStr);
+                //10.脉诊
+                calculatePulse(watchUserId, DateUtils.parseDateToStr("yyyy-MM-dd", currentStartDate), pulseStr, dateToStr);
+            }
+
+
+
+
+
+            //日期加1天
+            calendar.add(Calendar.DAY_OF_MONTH, 1);
+            setToStartOfDay(calendar);
+        }
+        if (spotStr.length() > 0) {
+            str.append("\n").append("【步行:").append(spotStr).append("】");
+        }
+        if (bpStr.length() > 0) {
+            str.append("\n").append("【血压:").append(bpStr).append("】");
+            isRequestAi = true;
+        }
+        if (bgStr.length() > 0) {
+            str.append("\n").append("【血糖:").append(bgStr).append("】");
+            isRequestAi = true;
+        }
+        if (hrStr.length() > 0) {
+            str.append("\n").append("【心率:").append(hrStr).append("】");
+            isRequestAi = true;
+        }
+        if (spo2Str.length() > 0) {
+            str.append("\n").append("【血氧:").append(spo2Str).append("】");
+            isRequestAi = true;
+        }
+        if (sleepStr.length() > 0) {
+            if (sleepStr.toString().endsWith(",")) {
+                sleepStr.deleteCharAt(sleepStr.length() - 1);
+            }
+            str.append("\n").append("【睡眠:").append(sleepStr).append("】");
+            isRequestAi = true;
+        }
+        if (tongueStr.length() > 0) {
+            str.append("\n").append("【舌诊:").append(tongueStr).append("】");
+            isRequestAi = true;
+        }
+        if (surfaceStr.length() > 0) {
+            str.append("\n").append("【面诊:").append(surfaceStr).append("】");
+            isRequestAi = true;
+        }
+        if (pulseStr.length() > 0) {
+            str.append("\n").append("【脉诊:").append(pulseStr).append("】");
+            isRequestAi = true;
+        }
+
+
+
+        if (StringUtils.isNotBlank(str) && isRequestAi) {
+            log.info("健康报告:{}", str);
+            message1.setContent(str.toString());
+            messageList.add(message1);
+
+
+            R r = chatService.initiatingTakeChat(param, AIURL, APPKEY);
+            if (r != null && r.get("data") != null) {
+                Object data = r.get("data");
+                if (!(data instanceof KnowledgeBaseResult)) {
+                    ChatDetailTStreamFResult result = (ChatDetailTStreamFResult) r.get("data");
+                    if (result != null) {
+                        List<ChatDetailTStreamFResult.Choice> choices = result.getChoices();
+                        //默认取第一条
+                        if (choices != null && choices.size() > 0) {
+                            ChatDetailTStreamFResult.Choice choice = choices.get(0);
+                            ChatDetailTStreamFResult.Choice.Message message = choice.message;
+                            if (message != null) {
+                                String content = message.getContent();
+                                if (StringUtils.isNotBlank(content)) {
+                                    aiSuggestion = content;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        res.setAiSuggestion(aiSuggestion);
     }
 
 
 
 
+    private void calculatePulse(Long userId, String date, StringBuilder pulseStr, String dateToStr) {
+        FsHealthPulseListUParam param = new FsHealthPulseListUParam();
+        param.setUserId(userId);
+        param.setCreateDay(date);
+
+        List<FsHealthPulseListVO> fsHealthPulseListVOS = fsHealthPulseMapper.selectFsHealthPulseListVO(param);
+        if (fsHealthPulseListVOS != null && !fsHealthPulseListVOS.isEmpty()) {
+            FsHealthPulseListVO vo = fsHealthPulseListVOS.get(0);
+
+            String leftJson = vo.getLeftHandResult();
+            String rightJson = vo.getRightHandResult();
+
+            String leftResult = "", leftSize = "", rightResult = "", rightSize = "";
+
+            try {
+                if (StringUtils.isNotEmpty(leftJson)) {
+                    JsonNode node = objectMapper.readTree(leftJson);
+                    leftResult = node.path("leftHandResult").asText("");
+                    leftSize = node.path("leftHandSize").asText("");
+                }
+
+                if (StringUtils.isNotEmpty(rightJson)) {
+                    JsonNode node = objectMapper.readTree(rightJson);
+                    rightResult = node.path("rightHandResult").asText("");
+                    rightSize = node.path("rightHandSize").asText("");
+                }
+            } catch (Exception e) {
+                log.error("解析脉象JSON失败: {}", e.getMessage());
+            }
+
+            pulseStr.append(dateToStr).append(" 左手 ").append(leftSize).append(" ").append("右手 ").append(rightSize).append(" ");
+        }
+    }
+
+
+    private void calculateSurface(Long userId, String date, StringBuilder surfaceStr, String dateToStr) {
+        FsHealthSurfaceListUParam param = new FsHealthSurfaceListUParam();
+        param.setUserId(userId);
+        param.setCreateDay(date);
+        List<FsHealthSurfaceListVO> fsHealthSurfaceListVOS = fsHealthSurfaceMapper.selectFsHealthSurfaceListVO(param);
+        if (fsHealthSurfaceListVOS != null && !fsHealthSurfaceListVOS.isEmpty()) {
+            FsHealthSurfaceListVO vo = fsHealthSurfaceListVOS.get(0);
+            surfaceStr.append(dateToStr).append(" ").append(vo.getComplexionResult()).append(" ").append(vo.getGlowResult()).append(" ").append(vo.getSwellingProblems()).append(" ");
+        }
+    }
+
+    /**
+     * 计算每天舌诊
+     *
+     * @param userId
+     * @param date
+     * @param tongueStr
+     * @param dateToStr
+     */
+    private void calculateTongue(Long userId, String date, StringBuilder tongueStr, String dateToStr) {
+        FsHealthTongueListUParam param = new FsHealthTongueListUParam();
+        param.setUserId(userId);
+        param.setCreateDay(date);
+        List<FsHealthTongueListUVO> vos = fsHealthTongueMapper.selectFsHealthTongueUListVO(param);
+        if (vos != null && !vos.isEmpty()) {
+            FsHealthTongueListUVO vo = vos.get(0);
+            tongueStr.append(dateToStr).append(" ").append(vo.getTypeName()).append(" ").append(vo.getShemianName()).append(" ").append(vo.getTaiseName()).append(" ");
+            try {
+                String chihenDesc = vo.getChihenDesc();
+                if (StringUtils.isNotBlank(chihenDesc)) {
+                    chihenDesc = chihenDesc.substring(1).split("表示")[0];
+                    tongueStr.append(chihenDesc).append(" ");
+                }
+                String liewenDesc = vo.getLiewenDesc();
+                if (StringUtils.isNotBlank(liewenDesc)) {
+                    liewenDesc = liewenDesc.substring(1).split("表示")[0];
+                    tongueStr.append(liewenDesc).append(" ");
+                }
+                String botaiDesc = vo.getBotaiDesc();
+                if (StringUtils.isNotBlank(botaiDesc)) {
+                    botaiDesc = botaiDesc.substring(1).split("表示")[0];
+                    tongueStr.append(botaiDesc).append(" ");
+                }
+                String taiseDesc = vo.getTaiseDesc();
+                if (StringUtils.isNotBlank(taiseDesc)) {
+                    tongueStr.append(taiseDesc).append(" ");
+                }
+            } catch (Exception e) {
+                log.error("舌苔详细解析错误{}错误信息:{}", vo, e.getMessage());
+            }
+
+        }
+    }
+
+    /**
+     * 计算每天睡眠
+     *
+     * @param deviceId
+     * @param date
+     * @param sleepStr
+     * @param dateToStr
+     */
+    private void calculateSleep(String deviceId, String date, StringBuilder sleepStr, String dateToStr,Integer deviceType) {
+        if (deviceType == null || deviceType == 0) {
+            WatchSleepDataVo vo = watchSleepDataService.getSleepSection(date, deviceId);
+            if (vo != null) {
+                if (StringUtils.isNotBlank(vo.getStartTime())) {
+                    sleepStr.append(dateToStr).append(" ").append(vo.getStartTime()).append("入睡,");
+                } else {
+                    return;
+                }
+                if (StringUtils.isNotBlank(vo.getEndTime())) {
+                    sleepStr.append(vo.getEndTime()).append("醒来,");
+                }
+                if (vo.getSleepTime() != null) {
+                    sleepStr.append("深睡 ").append(vo.getSleepTime()).append(" 分钟,");
+                }
+                if (vo.getLightSleep() != null) {
+                    sleepStr.append("浅睡 ").append(vo.getLightSleep()).append(" 分钟,");
+                }
+                if (vo.getEyemoveSleep() != null) {
+                    sleepStr.append("快速眼动 ").append(vo.getEyemoveSleep()).append(" 分钟,");
+                }
+                if (vo.getWeakSleep() != null) {
+                    sleepStr.append("清醒 ").append(vo.getWeakSleep()).append(" 分钟,");
+                }
+            }
+        } else {
+            Date dateTemp = DateUtils.dateTime("yyyy-MM-dd", date);
+            Date dayStartTime = DateUtils.truncate(dateTemp, Calendar.DATE);
+            Date dayEndTime =  DateUtils.addMilliseconds(
+                    DateUtils.addDays(DateUtils.truncate(dateTemp, Calendar.DATE), 1),
+                    -1
+            );
+            List<FsThirdDeviceData> list = fsThirdDeviceDataMapper.selectListByDateAndDeviceIdAndRecordType(dayStartTime, dayEndTime, deviceId, 7, null);
+            if (list != null && !list.isEmpty()) {
+                SleepStatistics sleepStatistics = SleepScoreCalculator.calculateDetailedStatistics(list);
+                sleepStr.append(dateToStr).append(" ").append(list.get(0).getCreateTime()).append("入睡,");
+                if (list.size() > 1) {
+                    sleepStr.append(list.get(list.size()-1).getCreateTime()).append("醒来,");
+                }
+                sleepStr.append("深睡 ").append(sleepStatistics.getDeepSleepHours()*60).append(" 分钟,");
+                sleepStr.append("浅睡 ").append(sleepStatistics.getLightSleepHours()*60).append(" 分钟,");
+                sleepStr.append("清醒 ").append(sleepStatistics.getAwakeHours()*60).append(" 分钟,");
+            }
+
+        }
+    }
+
+
+    /**
+     * 计算每天血氧
+     *
+     * @param deviceId
+     * @param currentStartDate
+     * @param currentEndDate
+     * @param spo2Str
+     * @param dateToStr
+     */
+    private void calculateSpo2(String deviceId, String currentStartDate, String currentEndDate, StringBuilder spo2Str,
+                               String dateToStr,Integer deviceType) {
+        Float value = null;
+        if (deviceType == null || deviceType == 1) {
+            value = watchSpo2DataMapper.countAvgBpByDate(currentStartDate, currentEndDate, deviceId);
+
+        } else {
+            value = fsThirdDeviceDataMapper.countAvgBpByDate(currentStartDate, currentEndDate, deviceId);
+        }
+        if (value != null) {
+            spo2Str.append(dateToStr).append(" ").append(value).append("% ");
+        }
+    }
+
+    /**
+     * 计算每天心率
+     *
+     * @param deviceId
+     * @param currentStartDate
+     * @param currentEndDate
+     * @param hrStr
+     * @param dateToStr
+     */
+    private void calculateHr(String deviceId, String currentStartDate, String currentEndDate, StringBuilder hrStr,
+                             String dateToStr,Integer deviceType) {
+        Map<String, Integer> map = null;
+        if (deviceType == null || deviceType == 0) {
+            map = watchHeartRateDataMapper.countMaxAndAvgBpByDate(currentStartDate, currentEndDate, deviceId);
+        } else {
+            map = fsThirdDeviceDataMapper.countMaxAndAvgBpByDate(currentStartDate, currentEndDate, deviceId);
+        }
+        if (map != null && map.get("avgBpm") != null && map.get("maxBpm") != null) {
+            hrStr.append(dateToStr).append(" 平均").append(map.get("avgBpm")).append(" 最高 ").append(map.get("maxBpm")).append(" ");
+        }
+    }
+
+    /**
+     * 计算每天血糖
+     *
+     * @param deviceId
+     * @param currentStartDate
+     * @param currentEndDate
+     * @param bgStr
+     */
+    private void calculateBg(String deviceId, String currentStartDate, String currentEndDate, StringBuilder bgStr,
+                             String dateToStr,Integer deviceType) {
+        if (deviceType == null || deviceType == 0) {
+            List<WatchBloodGlucoseData> bgData = watchBloodGlucoseDataMapper.queryBgByDate(currentStartDate, currentEndDate, deviceId, null);
+
+            if (bgData != null && !bgData.isEmpty()) {
+                WatchBloodGlucoseData watchBloodGlucoseData = bgData.get(bgData.size() - 1);
+                bgStr.append(dateToStr).append(" ").append(watchBloodGlucoseData.getBloodGlucose()).append("mmol/L ");
+            }
+        } else {
+            List<FsThirdDeviceData> bgData = fsThirdDeviceDataMapper.queryBgByDate(currentStartDate, currentEndDate, deviceId);
+
+            if (bgData != null && !bgData.isEmpty()) {
+                FsThirdDeviceData fsThirdDeviceData = bgData.get(bgData.size() - 1);
+                bgStr.append(dateToStr).append(" ").append(fsThirdDeviceData.getRecordValue()).append("mmol/L ");
+            }
+        }
+
+    }
+
+    /**
+     * 计算每天血压
+     *
+     * @param deviceId
+     * @param currentStartDate
+     * @param currentEndDate
+     * @param bpStr
+     */
+    private void calculateBp(String deviceId, String currentStartDate, String currentEndDate, StringBuilder bpStr
+            , String dateToStr,Integer deviceType) {
+        Map<String, Integer> map = new HashMap<>();
+        if(deviceType == null || deviceType == 0){
+            //原腕表
+            map = watchBloodPressureDataMapper.countMaxAndMinBpByDate(currentStartDate, currentEndDate, deviceId);
+        } else {
+            //小护士
+            map = fsThirdDeviceDataMapper.countMaxAndMinBpByDate(currentStartDate, currentEndDate, deviceId);
+        }
+        if (map != null && map.get("max") != null && map.get("min") != null) {
+            bpStr.append(dateToStr).append(" 高压 ").append(map.get("max")).append(" 低压 ").append(map.get("min")).append(" ");
+        }
+
+
+    }
+
+    /**
+     * 计算每天步数总和
+     *
+     * @param deviceId
+     * @param currentStartDate
+     * @param currentEndDate
+     * @param spotStr
+     */
+    private void calculateStep(String deviceId, String currentStartDate, String currentEndDate, StringBuilder spotStr,
+                               String dateToStr,Integer deviceType) {
+        long dailyStep = 0;
+        if (deviceType == null || deviceType == 0) {
+            List<WatchSportData> list = sportDataMapper.getByType(currentStartDate, currentEndDate, deviceId, null);
+            if (list != null && !list.isEmpty()) {
+                for (WatchSportData data : list) {
+                    dailyStep += data.getStep() == null ? 0 : data.getStep();
+                }
+            }
+
+        } else {
+            //小护士设备
+            WatchSportRecordVo otherData1 = fsThirdDeviceDataMapper.getOtherData(DateUtils.dateTime("yyyy-MM-dd HH:mm:ss", currentStartDate),
+                    DateUtils.dateTime("yyyy-MM-dd HH:mm:ss", currentEndDate), deviceId, 5, null);
+            WatchSportRecordVo otherData2 = fsThirdDeviceDataMapper.getOtherData(DateUtils.dateTime("yyyy-MM-dd HH:mm:ss", currentStartDate),
+                    DateUtils.dateTime("yyyy-MM-dd HH:mm:ss", currentEndDate), deviceId, 6, null);
+            if (otherData1 != null){
+                dailyStep = dailyStep + (otherData1.getStep() == null?0:otherData1.getStep());
+            }
+            if (otherData2 != null){
+                dailyStep = dailyStep + (otherData2.getStep() == null?0:otherData2.getStep());
+            }
+        }
+        if (dailyStep > 0) {
+            spotStr.append(dateToStr).append(" ").append(dailyStep).append("步 ");
+        }
+    }
+
+    /**
+     * 将日历设置为当天的开始时间(00:00:00)
+     */
+    private void setToStartOfDay(Calendar calendar) {
+        calendar.set(Calendar.HOUR_OF_DAY, 0);
+        calendar.set(Calendar.MINUTE, 0);
+        calendar.set(Calendar.SECOND, 0);
+        calendar.set(Calendar.MILLISECOND, 0);
+    }
+
+
     public <T extends Enum<T> & HealthStatusEnum> void getHealth(
             List<Map<String, Object>> data,
             List<AppHealthReportVo> vos,
             Class<T> enumClass,
-            AtomicInteger  score
+            AtomicInteger score
     ) {
         if (data == null) {
             return;
@@ -281,7 +890,7 @@ public class WatchBasicInfoServiceImpl implements WatchBasicInfoService {
             Integer status = Integer.valueOf(map.get("status").toString());
             Integer count = Integer.valueOf(map.get("count").toString());
             if (count > 0) {
-                AppHealthReportVo vo = createHealthReportVo(status, count, enumClass,score);
+                AppHealthReportVo vo = createHealthReportVo(status, count, enumClass, score);
                 if (vo != null) {
                     vos.add(vo);
                 }
@@ -293,7 +902,7 @@ public class WatchBasicInfoServiceImpl implements WatchBasicInfoService {
             Integer status,
             Integer count,
             Class<T> enumClass,
-            AtomicInteger  score
+            AtomicInteger score
     ) {
         if (status == null || enumClass == null) return null;
 
@@ -310,7 +919,7 @@ public class WatchBasicInfoServiceImpl implements WatchBasicInfoService {
         vo.setSuggestion(matchedEnum.getSuggestion());
         vo.setPrecautions(matchedEnum.getPrecautions());
         //扣得分 出现一次异常减5分,无数据不扣分
-        score.addAndGet(-(5*count)); // 异常就减分
+        score.addAndGet(-(5 * count)); // 异常就减分
         return vo;
     }
 

+ 107 - 24
fs-service/src/main/java/com/fs/watch/service/impl/WatchBloodGlucoseDataServiceImpl.java

@@ -2,6 +2,8 @@ package com.fs.watch.service.impl;
 
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.StringUtils;
+import com.fs.his.domain.FsThirdDeviceData;
+import com.fs.his.mapper.FsThirdDeviceDataMapper;
 import com.fs.watch.domain.WatchBloodGlucoseData;
 import com.fs.watch.domain.WatchDeviceInfo;
 import com.fs.watch.enums.WatchBgStatusEnum;
@@ -30,15 +32,12 @@ public class WatchBloodGlucoseDataServiceImpl implements WatchBloodGlucoseDataSe
     private WatchThirdBpDataService watchThirdBpDataService;
     @Autowired
     private WatchDeviceInfoMapper watchDeviceInfoMapper;
+    @Autowired
+    private FsThirdDeviceDataMapper fsThirdDeviceDataMapper;
 
 
     @Override
     public Boolean insert(WatchBloodGlucoseData watchBloodGlucoseData) {
-        //判断创建时间是否唯一
-        Integer num = mapper.queryByCreateTime(watchBloodGlucoseData.getCreateTime());
-        if (num != null && num > 0) {
-            return false;
-        }
         try {
             mapper.insert(watchBloodGlucoseData);
         } catch (Exception e) {
@@ -80,27 +79,56 @@ public class WatchBloodGlucoseDataServiceImpl implements WatchBloodGlucoseDataSe
     }
 
     @Override
-    public List<WatchBloodGlucoseData> queryBgByDate(Date startTime, Date endTime, String deviceId, Integer status) {
+    public List<WatchBloodGlucoseData> queryBgByDate(Date startTime, Date endTime, String deviceId, Integer status,Integer deviceType) {
         if (StringUtils.isNotBlank(deviceId)) {
-            List<WatchBloodGlucoseData> data = mapper.queryBgByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
-                    DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),
-                    deviceId,
-                    status);
-            return data;
+            if (deviceType == null || deviceType == 0) {
+                return mapper.queryBgByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
+                        DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),
+                        deviceId,
+                        status);
+            } else {
+                List<FsThirdDeviceData> list = fsThirdDeviceDataMapper.selectListByDateAndDeviceIdAndRecordType(startTime, endTime, deviceId, 1, status);
+                if (list != null && !list.isEmpty()) {
+                    List<WatchBloodGlucoseData> voList= new ArrayList<>();
+                    list.forEach(fsThirdDeviceData -> {
+                        WatchBloodGlucoseData data = new WatchBloodGlucoseData();
+                        data.setDeviceId(fsThirdDeviceData.getDeviceId());
+                        String recordValue = fsThirdDeviceData.getRecordValue();
+                        if (recordValue != null) {
+                            // 移除所有双引号
+                            recordValue = recordValue.replace("\"", "");
+                            // 或者只移除首尾的引号和可能的空格
+                            recordValue = recordValue.replaceAll("^[\"']+|[\"']+$", "");
+                        }
+                        data.setBloodGlucose(Float.valueOf(recordValue));
+                        data.setCreateTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",fsThirdDeviceData.getCreateTime()));
+                        data.setStatus(fsThirdDeviceData.getStatus());
+                        voList.add(data);
+                    });
+                    return voList;
+                }
+            }
+
         }
         return null;
     }
 
 
     @Override
-    public List<Map<String, Object>> countBgByDate(Date startTime, Date endTime, String deviceId) {
+    public List<Map<String, Object>> countBgByDate(Date startTime, Date endTime, String deviceId,Integer deviceType) {
         if (StringUtils.isBlank(deviceId)) {
             return null;
         }
         //返回对象
         List<Map<String, Object>> res = null;
-        res = mapper.countBpByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
-                DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime), deviceId);
+        if (deviceType == null || deviceType == 0) {
+            res = mapper.countBpByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
+                    DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime), deviceId);
+        } else {
+            res = fsThirdDeviceDataMapper.countByDateAndDeviceIdAndRecordType(startTime, endTime, deviceId, 1,null);
+        }
+
+
 
         return res;
     }
@@ -111,20 +139,75 @@ public class WatchBloodGlucoseDataServiceImpl implements WatchBloodGlucoseDataSe
     }
 
     @Override
-    public int countBgPageByDate(Date startTime, Date endTime, String deviceId, Integer status) {
-        return mapper.countBgPageByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
-                DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),
-                deviceId, status);
+    public int countBgPageByDate(Date startTime, Date endTime, String deviceId, Integer status,Integer deviceType) {
+        if (deviceType == null || deviceType == 0) {
+            return mapper.countBgPageByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
+                    DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),
+                    deviceId, status);
+        } else {
+            return fsThirdDeviceDataMapper.countPageByDateAndDeviceIdAndRecordType(startTime,endTime,deviceId,1,status);
+        }
+
     }
 
     @Override
-    public List<WatchBloodGlucoseData> queryBgPageByDate(Date startTime, Date endTime, String deviceId, Integer status, Integer num, Integer size) {
-        if (StringUtils.isNotBlank(deviceId)) {
-            return mapper.queryBgPageByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
-                    DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),
-                    deviceId, status, num, size);
+    public List<WatchBloodGlucoseData> queryBgPageByDate(Date startTime, Date endTime, String deviceId, Integer status, Integer num, Integer size,Integer deviceType) {
+        if (deviceType == null || deviceType == 0) {
+            if (StringUtils.isNotBlank(deviceId)) {
+                return mapper.queryBgPageByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
+                        DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),
+                        deviceId, status, num, size);
+            } else {
+                return null;
+            }
         } else {
-            return null;
+            List<WatchBloodGlucoseData> voList= new ArrayList<>();
+            List<FsThirdDeviceData> list = fsThirdDeviceDataMapper.queryPageByDateAndDeviceIdAndRecordType(startTime, endTime, deviceId, 1,status, num, size);
+            if (list != null && !list.isEmpty()) {
+                list.forEach(fsThirdDeviceData -> {
+                    WatchBloodGlucoseData data = new WatchBloodGlucoseData();
+                    data.setDeviceId(fsThirdDeviceData.getDeviceId());
+                    String recordValue = fsThirdDeviceData.getRecordValue();
+                    if (recordValue != null) {
+                        // 移除所有双引号
+                        recordValue = recordValue.replace("\"", "");
+                        // 或者只移除首尾的引号和可能的空格
+                        recordValue = recordValue.replaceAll("^[\"']+|[\"']+$", "");
+                    }
+                    data.setBloodGlucose(Float.valueOf(recordValue));
+                    data.setCreateTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",fsThirdDeviceData.getCreateTime()));
+                    data.setStatus(fsThirdDeviceData.getStatus());
+                    voList.add(data);
+                });
+
+            }
+            return voList;
         }
+
     }
+
+    /**
+     * 高风险:血糖值大于等于 7.0 mmol/L,返回 1。
+     * 一般:血糖值在 6.0 mmol/L 和 7.0 mmol/L 之间,返回 3。
+     * 良好:血糖值在 5.0 mmol/L 和 6.0 mmol/L 之间,返回 4。
+     * 正常:血糖值在 3.9 mmol/L和 4.0 mmol/L 之间,,返回 5。
+     * 不良:血糖值小于 3.9 mmol/L 之间,返回 2。
+     * 获得血糖状态
+     *
+     * @param num
+     * @return 状态码
+     */
+    @Override
+    public Integer getStatus(Double num) {
+        if (num >= 7.0) {
+            return WatchBgStatusEnum.HYPERGLYCEMIA.getValue(); // 高风险(糖尿病)
+        } else if (num >= 6.1) {
+            return WatchBgStatusEnum.HIGHER.getValue(); // 一般(糖尿病前期)
+        } else if (num >= 3.9) {
+            return WatchBgStatusEnum.NORMAL.getValue(); // 良好正常
+        } else {
+            return WatchBgStatusEnum.HYPOGLYCEMIA.getValue(); //不良 (低血糖)
+        }
+    }
+
 }

+ 38 - 6
fs-service/src/main/java/com/fs/watch/service/impl/WatchBloodPressureDataServiceImpl.java

@@ -35,11 +35,6 @@ public class WatchBloodPressureDataServiceImpl implements WatchBloodPressureData
 
     @Override
     public Boolean insert(WatchBloodPressureData watchBloodPressureData) {
-        //判断创建时间是否唯一
-        Integer num = mapper.queryByCreateTime(watchBloodPressureData.getCreateTime());
-        if (num != null && num > 0) {
-            return false;
-        }
         try {
             mapper.insert(watchBloodPressureData);
         } catch (Exception e) {
@@ -94,7 +89,7 @@ public class WatchBloodPressureDataServiceImpl implements WatchBloodPressureData
                     DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
                     DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),
                     deviceId,
-                    status);
+                    status,0);
             if (!watchThirdBpDatas.isEmpty()){
                 return watchThirdBpDatas;
             } else {
@@ -162,4 +157,41 @@ public class WatchBloodPressureDataServiceImpl implements WatchBloodPressureData
             return null;
         }
     }
+
+    /**
+     * 重度: 收缩压 > 180 mmHg 或 舒张压 > 110 mmHg 1
+     * 中度: 收缩压在 160-179 mmHg 之间 或 舒张压在 100-109 mmHg 之间 2
+     * 轻度: 收缩压在 140-159 mmHg 之间 或 舒张压在 90-99 mmHg 之间 3
+     * 正常高值: 收缩压在 130-139 mmHg 之间 或 舒张压在 85-89 mmHg 之间 4
+     * 偏低: 收缩压 < 90 mmHg 或 舒张压 < 60 mmHg 5
+     * 正常: 收缩压在 90-139 mmHg 之间 且 舒张压在 60-89 mmHg 之间 6
+     * @param sbp
+     * @param dbp
+     * @return
+     */
+    @Override
+    public Integer getStatus(int sbp, int dbp) {
+        int status;
+//        if (sbp > 180 || dbp > 110) {
+//            status = 1; // 重度
+//        } else if (sbp >= 160 || dbp >= 100) {
+//            status = 2; // 中度
+//        } else if (sbp >= 140 || dbp >= 90) {
+//            status = 3; // 轻度
+//        } else if (sbp >= 130 || dbp >= 85) {
+//            status = 4; // 正常高值
+//        } else if (sbp < 90 || dbp < 60) {
+//            status = 5; // 偏低
+//        } else {
+//            status = 6; // 正常
+//        }
+        if (sbp >= 140 || dbp >=90 ) {
+            status = WatchBpStatusEnum.HYPERTENSION.getValue(); // 重度(高血压)
+        } else if (sbp >= 90 || dbp >= 60) {
+            status = WatchBpStatusEnum.NORMAL.getValue(); // 正常范围
+        } else {
+            status = WatchBpStatusEnum.HYPOTENSION.getValue(); // 低血压
+        }
+        return status;
+    }
 }

+ 0 - 4
fs-service/src/main/java/com/fs/watch/service/impl/WatchContinuousSpo2DataServiceImpl.java

@@ -27,10 +27,6 @@ public class WatchContinuousSpo2DataServiceImpl implements WatchContinuousSpo2Da
 
     @Override
     public Boolean insert(WatchContinuousSpo2Data watchContinuousSpo2Data) {
-        Integer num = mapper.queryByCreateTime(watchContinuousSpo2Data.getCreateTime());
-        if (num != null && num > 0) {
-            return false;
-        }
         try {
             mapper.insert(watchContinuousSpo2Data);
         } catch (Exception e) {

+ 314 - 116
fs-service/src/main/java/com/fs/watch/service/impl/WatchDataServiceImpl.java

@@ -6,11 +6,15 @@ import com.alibaba.fastjson.JSONObject;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.StringUtils;
 import com.fs.his.domain.FsHealthTongue;
+import com.fs.his.domain.FsThirdDeviceData;
+import com.fs.his.mapper.FsThirdDeviceDataMapper;
 import com.fs.his.utils.PhoneUtil;
+import com.fs.watch.calculation.SleepScoreCalculator;
 import com.fs.watch.domain.*;
 import com.fs.watch.domain.vo.*;
 import com.fs.watch.enums.*;
 import com.fs.watch.mapper.*;
+import com.fs.watch.param.WatchUserByDeviceIdParam;
 import com.fs.watch.service.*;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -71,9 +75,11 @@ public class WatchDataServiceImpl implements WatchDataService {
     private WatchSpo2DataService watchSpo2DataService;
     @Autowired
     private WatchFatigueDataService watchFatigueDataService;
+    @Autowired
+    private FsThirdDeviceDataMapper fsThirdDeviceDataMapper;
 
     @Override
-    public List<FsMonitorDataVo> queryIndexWatchData(List<String> types, String deviceId,String userId) {
+    public List<FsMonitorDataVo> queryIndexWatchData(List<String> types, String deviceId,String userId,Integer deviceType) {
         //返回对象
         List<FsMonitorDataVo> vos = new ArrayList<>();
         for (String typeStr : types) {
@@ -88,43 +94,90 @@ public class WatchDataServiceImpl implements WatchDataService {
             int type = Integer.parseInt(typeStr);
             switch (type) {
                 case 1:  //血糖
-                    WatchBloodGlucoseData bgData = watchBloodGlucoseDataService.getLatest(deviceId);
-                    if (bgData != null) {
+                    if (deviceId == null || deviceType == 0) {
+                        WatchBloodGlucoseData bgData = watchBloodGlucoseDataService.getLatest(deviceId);
+                        if (bgData != null) {
 //                        vo.setDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,bgData.getCreateTime()));
-                        vo.setDate(bgData.getCreateTime());
-                        vo.setData(bgData.getBloodGlucose().toString());
+                            vo.setDate(bgData.getCreateTime());
+                            vo.setData(bgData.getBloodGlucose().toString());
+                        } else {
+                            vo.setData("");
+                        }
                     } else {
-                        vo.setData("");
+                        FsThirdDeviceData data = fsThirdDeviceDataMapper.getLatest(deviceId,1);
+                        if (data != null) {
+//                        vo.setDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,bgData.getCreateTime()));
+                            vo.setDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,data.getCreateTime()));
+                            vo.setData(data.getRecordValue());
+                        } else {
+                            vo.setData("");
+                        }
                     }
+
+
                     vos.add(vo);
                     break;
                 case 2:  //血压
-                    WatchThirdBpData bpData = watchBloodPressureDataService.getLatest(deviceId);
-                    if (bpData != null) {
+                    if (deviceId == null || deviceType == 0) {
+                        WatchThirdBpData bpData = watchBloodPressureDataService.getLatest(deviceId);
+                        if (bpData != null) {
 //                        vo.setDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,bpData.getCreateTime()));
-                        vo.setDate(bpData.getCreateTime());
-                        vo.setData(bpData.getDbp() + "/" + bpData.getSbp().toString());
+                            vo.setDate(bpData.getCreateTime());
+                            vo.setData(bpData.getDbp() + "/" + bpData.getSbp().toString());
+                        } else {
+                            vo.setData("");
+                        }
                     } else {
-                        vo.setData("");
+                        FsThirdDeviceData data = fsThirdDeviceDataMapper.getLatest(deviceId,0);
+                        if (data != null) {
+//                        vo.setDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,bgData.getCreateTime()));
+                            vo.setDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,data.getCreateTime()));
+                            String recordValue = data.getRecordValue();
+                            if (StringUtils.isNotBlank(recordValue)) {
+                                JSONObject jsonObject = JSONObject.parseObject(recordValue);
+                                String sdb = jsonObject.get("sdb").toString();
+                                String dbp = jsonObject.get("dbp").toString();
+                                vo.setData(dbp + "/" + sdb );
+                            } else {
+                                vo.setData("");
+                            }
+                        } else {
+                            vo.setData("");
+                        }
                     }
+
                     vos.add(vo);
                     break;
                 case 3:  //心率
-                    WatchHeartRateData hrData = watchHeartRateDataService.getLatest(deviceId);
-                    if (hrData != null) {
+                    if (deviceId == null || deviceType == 0) {
+                        WatchHeartRateData hrData = watchHeartRateDataService.getLatest(deviceId);
+                        if (hrData != null) {
 //                        vo.setDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,hrData.getCreateTime()));
-                        vo.setDate(hrData.getCreateTime());
-                        vo.setData(hrData.getAvgBpm().toString());
+                            vo.setDate(hrData.getCreateTime());
+                            vo.setData(hrData.getAvgBpm().toString());
+                        } else {
+                            vo.setData("");
+                        }
                     } else {
-                        vo.setData("");
+                        FsThirdDeviceData data = fsThirdDeviceDataMapper.getLatest(deviceId,2);
+                        if (data != null) {
+//                        vo.setDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,bgData.getCreateTime()));
+                            vo.setDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,data.getCreateTime()));
+                            vo.setData(data.getRecordValue());
+                        } else {
+                            vo.setData("");
+                        }
                     }
+
+
                     vos.add(vo);
                     break;
                 case 4:  //血氧
-                    WatchSpo2DataVo spo2DataVo = watchSpo2DataService.getLatest(deviceId);
-                    if (spo2DataVo != null) {
-                        vo.setDate(spo2DataVo.getCreateTime());
-                        vo.setData(spo2DataVo.getAvgBoxy().toString());
+                    if (deviceId == null || deviceType == 0) {
+                        WatchSpo2DataVo spo2DataVo = watchSpo2DataService.getLatest(deviceId);
+                        if (spo2DataVo != null) {
+                            vo.setDate(spo2DataVo.getCreateTime());
+                            vo.setData(spo2DataVo.getAvgBoxy().toString());
 
 //                    WatchContinuousSpo2Data continuousSpo2Data = watchContinuousSpo2DataService.getLastByDeviceId(deviceId);
 //                    if (continuousSpo2Data != null) {
@@ -150,75 +203,159 @@ public class WatchDataServiceImpl implements WatchDataService {
 //                        } else {
 //                            vo.setData("");
 //                        }
+                        } else {
+                            vo.setData("");
+                        }
                     } else {
-                        vo.setData("");
+                        FsThirdDeviceData data = fsThirdDeviceDataMapper.getLatest(deviceId,4);
+                        if (data != null) {
+//                        vo.setDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,bgData.getCreateTime()));
+                            vo.setDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,data.getCreateTime()));
+                            vo.setData(data.getRecordValue());
+                        } else {
+                            vo.setData("");
+                        }
                     }
+
+
                     vos.add(vo);
                     break;
                 case 5:  //体温
-                    WatchTemperatureData temperatureData = watchTemperatureDataService.getLatest(deviceId);
-                    if (temperatureData != null) {
+                    if (deviceId == null || deviceType == 0) {
+                        WatchTemperatureData temperatureData = watchTemperatureDataService.getLatest(deviceId);
+                        if (temperatureData != null) {
 //                        vo.setDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,temperatureData.getCreateTime()));
-                        vo.setDate(temperatureData.getCreateTime());
-                        vo.setData(temperatureData.getEstTemp().toString());
+                            vo.setDate(temperatureData.getCreateTime());
+                            vo.setData(temperatureData.getEstTemp().toString());
+                        } else {
+                            vo.setData("");
+                        }
                     } else {
                         vo.setData("");
                     }
+
+
                     vos.add(vo);
                     break;
                 case 6:  //呼吸 todo
-                    vo.setDate(DateUtils.dateTimeNow());
-                    vo.setData(120 + "");
+                    if (deviceId == null || deviceType == 0) {
+                        vo.setDate(DateUtils.dateTimeNow());
+                        vo.setData(120 + "");
+                    } else {
+                        vo.setDate(DateUtils.dateTimeNow());
+                        vo.setData(120 + "");
+
+                    }
+
                     vos.add(vo);
                     break;
                 case 7:  //血脂 todo
-                    vo.setData("");
+                    if (deviceId == null || deviceType == 0) {
+                        vo.setData("");
+                    } else {
+                        vo.setData("");
+                    }
+
+
+
                     vos.add(vo);
                     break;
                 case 8:  //尿酸
-                    WatchThirdUaData uaData = watchThirdUaDataService.getLatest(deviceId);
-                    if (uaData != null) {
-                        vo.setDate(uaData.getCreateTime());
-                        vo.setData(WatchUaStatusEnum.toType(
-                                watchThirdUaDataService.getStatus(deviceId,uaData.getVal(),Long.parseLong(userId),0)
-                        ).getDesc());
+                    if (deviceId == null || deviceType == 0) {
+                        WatchThirdUaData uaData = watchThirdUaDataService.getLatest(deviceId);
+                        if (uaData != null) {
+                            vo.setDate(uaData.getCreateTime());
+                            vo.setData(WatchUaStatusEnum.toType(
+                                    watchThirdUaDataService.getStatus(deviceId,uaData.getVal(),Long.parseLong(userId),0)
+                            ).getDesc());
+                        } else {
+                            vo.setData("");
+                        }
                     } else {
-                        vo.setData("");
+                        FsThirdDeviceData data = fsThirdDeviceDataMapper.getLatest(deviceId,3);
+                        if (data != null) {
+//                        vo.setDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,bgData.getCreateTime()));
+                            vo.setDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,data.getCreateTime()));
+                            vo.setData(data.getRecordValue());
+                        } else {
+                            vo.setData("");
+                        }
                     }
+
+
+
+
                     vos.add(vo);
                     break;
                 case 9:  //血管硬化 todo
-                    vo.setData("");
+                    if (deviceId == null || deviceType == 0) {
+                        vo.setData("");
+                    } else {
+                        vo.setData("");
+                    }
+
+
+
+
                     vos.add(vo);
                     break;
                 case 10:  //血酮
-                    WatchThirdBkData bkData = watchThirdBkDataService.getLatest(deviceId);
-                    if (bkData != null) {
+                    if (deviceId == null || deviceType == 0) {
+                        WatchThirdBkData bkData = watchThirdBkDataService.getLatest(deviceId);
+                        if (bkData != null) {
 //                        vo.setDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,bkData.getCreateTime()));
-                        vo.setDate(bkData.getCreateTime());
+                            vo.setDate(bkData.getCreateTime());
 //                        list.add(bkData.getVal().toString());
-                        Integer status = bkData.getStatus();
-                        vo.setData(status == 0 ? "正常" : "异常");
+                            Integer status = bkData.getStatus();
+                            vo.setData(status == 0 ? "正常" : "异常");
+                        } else {
+                            vo.setData("");
+                        }
                     } else {
                         vo.setData("");
                     }
+
+
+
                     vos.add(vo);
                     break;
                 case 11:  //睡眠 todo 未确定返回数据
-                    //查询最新日期
-                    WatchSleepData data = watchSleepDataService.getLast(deviceId);
-                    if (data != null) {
-                        String date = data.getCreateTime().split(" ")[0];
-                        WatchSleepDataVo sleepSection = watchSleepDataService.getSleepSection(date, deviceId);
-                        if (sleepSection != null) {
-                            vo.setDate(date);
-                            Integer score = sleepSection.getScore();
-                            vo.setData(score==null?"":score.toString());
+                    if (deviceId == null || deviceType == 0) {
+                        //查询最新日期
+                        WatchSleepData data = watchSleepDataService.getLast(deviceId);
+                        if (data != null) {
+                            String date = data.getCreateTime().split(" ")[0];
+                            WatchSleepDataVo sleepSection = watchSleepDataService.getSleepSection(date, deviceId);
+                            if (sleepSection != null) {
+                                vo.setDate(date);
+                                Integer score = sleepSection.getScore();
+                                vo.setData(score==null?"":score.toString());
+                                vos.add(vo);
+                                break;
+                            }
+                        }
+                        vo.setData("");
+                    } else {
+                        FsThirdDeviceData data = fsThirdDeviceDataMapper.getLatest(deviceId, 7);
+                        if (data != null) {
+                            Date endTime = data.getCreateTime();
+                            vo.setDate(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", endTime));
+                            Date starTime = DateUtils.truncate(endTime, Calendar.DATE);
+                            List<FsThirdDeviceData> list = fsThirdDeviceDataMapper.selectListByDateAndDeviceIdAndRecordType(starTime, endTime, deviceId, 7, null);
+                            // 计算睡眠评分
+                            int score = 0;
+//                            SleepStatistics statistics = null;
+                            if (list != null && !list.isEmpty()) {
+                                // 计算详细统计信息
+//                                statistics = SleepScoreCalculator.calculateDetailedStatistics(list);
+                                score = SleepScoreCalculator.calculateSleepScore(list);
+                            }
+                            vo.setData(String.valueOf(score));
                             vos.add(vo);
                             break;
                         }
+                        vo.setData("");
                     }
-                    vo.setData("");
                     vos.add(vo);
                     break;
 //                case 12:  //房颤 todo 未确定返回数据
@@ -236,13 +373,19 @@ public class WatchDataServiceImpl implements WatchDataService {
                     vos.add(vo);
                     break;
                 case 13:  //压力
-                    WatchFatigueData fatigue = watchFatigueDataService.getLastByDeviceId(deviceId);
-                    if (fatigue != null){
-                        vo.setDate(fatigue.getCreateTime());
-                        vo.setData(WatchFatigueStatusEnum.toType(fatigue.getStatus()).getDesc());
+                    if (deviceId == null || deviceType == 0) {
+                        WatchFatigueData fatigue = watchFatigueDataService.getLastByDeviceId(deviceId);
+                        if (fatigue != null){
+                            vo.setDate(fatigue.getCreateTime());
+                            vo.setData(WatchFatigueStatusEnum.toType(fatigue.getStatus()).getDesc());
+                        } else {
+                            vo.setData("");
+                        }
                     } else {
                         vo.setData("");
                     }
+
+
                     vos.add(vo);
                     break;
                 default:
@@ -253,51 +396,64 @@ public class WatchDataServiceImpl implements WatchDataService {
     }
 
     @Override
-    public List<AppInfoVo> getUserByDeviceId(String deviceIds, Boolean isFamily,Long userId) {
-        List<String> list = Arrays.asList(deviceIds.split(","));
-        WatchFsUser user = null;
-        if (list != null && list.size() > 0) {
-            //设备绑定用户名
-            user = userService.selectWatchFsUserByDeviceIdAndUserId(list.get(0), userId,isFamily?1:0);
+    public List<AppInfoVo> getUserByDeviceId(WatchUserByDeviceIdParam watchUserByDeviceIdParam, Long userId) {
+        List<WatchUserByDeviceIdParam.WatchUserByDeviceIdTemp> params = watchUserByDeviceIdParam.getParams();
+        Boolean isFamily = watchUserByDeviceIdParam.getIsFamily();
+        List<AppInfoVo> vos = new ArrayList<>();
+        for (WatchUserByDeviceIdParam.WatchUserByDeviceIdTemp temp : params) {
+            WatchFsUser user = null;
+            String deviceId = temp.getDeviceId();
+            Integer deviceType = temp.getDeviceType();
+            if (deviceType == null || deviceType == 0) {
+                user = userService.selectWatchFsUserByDeviceIdAndUserId(deviceId, userId, isFamily ? 1 : 0);
+            } else if (deviceType == 1) {
+                user = userService.selectWatchFsUserByDeviceIdAndUserId(deviceId, userId, isFamily ? 3 : 2);
+            }else if (deviceType == 2){
+                user = userService.selectWatchFsUserByDeviceIdAndUserId(deviceId, userId, isFamily ? 5: 4);
+            }
             if (user != null) {
                 //处理电话
                 String phone = user.getPhone();
                 if (StringUtils.isNotBlank(phone)) {
                     if (phone.length() != 11 && !phone.startsWith("1")) {
-                        user.setPhone(PhoneUtil.decryptPhone(phone));
+                        user.setPhone(PhoneUtil.decryptPhoneMk(phone));
                     }
                 }
             }
 
             if (!isFamily && user == null) {
-                return null;
+                continue;
             }
-            List<AppInfoVo> vos = new ArrayList<>();
-            for (String deviceId : list) {
-                AppInfoVo appInfoVo = new AppInfoVo();
-                appInfoVo.setUser(user);
-                //设备型号
-                WatchDeviceData data = watchDeviceDataMapper.getByDeviceId(deviceId);
+
+            AppInfoVo appInfoVo = new AppInfoVo();
+            appInfoVo.setUser(user);
+            //设备型号
+            WatchDeviceData data = null;
+            Map<String, Object> statusData = null;
+            if (deviceType == null || deviceType == 0) {
+                data = watchDeviceDataMapper.getByDeviceId(deviceId);
                 if (data != null) {
                     appInfoVo.setBle(data.getBle());
                 } else {
                     appInfoVo.setBle("H102C");
                 }
                 //获取设备状态
-                Map<String, Object> statusData = deviceInfoService.getInfo(deviceId);
+                statusData = deviceInfoService.getInfo(deviceId);
                 if (statusData == null) {
                     appInfoVo.setStatus(3);
                 } else if (statusData.get("status") != null) {
                     appInfoVo.setStatus(Integer.parseInt(statusData.get("status").toString()));
                 }
-                vos.add(appInfoVo);
-
-
+            } else if (deviceType == 1) {
+                appInfoVo.setBle("小护士设备:" + deviceId);
+                appInfoVo.setStatus(3);
+            } else if (deviceType == 2) {
+                appInfoVo.setBle("小护士手表:" + deviceId);
+                appInfoVo.setStatus(3);
             }
-            return vos;
-        } else {
-            return null;
+            vos.add(appInfoVo);
         }
+        return vos;
 
     }
 
@@ -459,19 +615,28 @@ public class WatchDataServiceImpl implements WatchDataService {
     }
 
     @Override
-    public QueryPageMonthVo queryMonthByDeviceId(String deviceId, Integer pageSize, Integer pageNum) {
+    public QueryPageMonthVo queryMonthByDeviceId(String deviceId, Integer pageSize, Integer pageNum,Integer deviceType) {
         if (StringUtils.isBlank(deviceId)) {
             return null;
         }
-        //从watch_device_data有数据开始
-        WatchDeviceData lastByDeviceId = watchDeviceDataMapper.getByDeviceId(deviceId);
-        if (lastByDeviceId == null) {
-            return null;
+        Date createTime = null;
+        List<String> monthList = null;
+        if (deviceType == null || deviceType == 0) {
+            //从watch_device_data有数据开始
+            WatchDeviceData lastByDeviceId = watchDeviceDataMapper.getByDeviceId(deviceId);
+            if (lastByDeviceId == null) {
+                return null;
+            }
+            // 获取设备创建时间
+            createTime = DateUtils.dateTime("yyyy-MM-dd HH:mm:ss",lastByDeviceId.getCreateTime());
+        } else {
+            FsThirdDeviceData firstDataByDeviceId = fsThirdDeviceDataMapper.getFirstDataByDeviceId(deviceId);
+            if (firstDataByDeviceId == null) {
+                return null;
+            }
+            createTime = firstDataByDeviceId.getCreateTime();
         }
 
-        List<String> monthList = null;
-        // 获取设备创建时间
-        Date createTime = DateUtils.dateTime("yyyy-MM-dd HH:mm:ss",lastByDeviceId.getCreateTime());
 
         // 获取当前时间
         Calendar current = Calendar.getInstance();
@@ -491,7 +656,7 @@ public class WatchDataServiceImpl implements WatchDataService {
 
             //有数据才添加
             //
-            Boolean flag = isHavingData(deviceId, monthStr);
+            Boolean flag = isHavingData(deviceId, monthStr,deviceType);
             if (flag){
                 // 获取当前日期并格式化为yyyy-MM,并存入列表
                 monthList.add(dateFormat.format(calendar.getTime()));
@@ -510,36 +675,69 @@ public class WatchDataServiceImpl implements WatchDataService {
         return vo;
     }
 
-    private  Boolean isHavingData(String deviceId, String monthStr) {
+    private  Boolean isHavingData(String deviceId, String monthStr,Integer deviceType) {
         boolean flag = false;
-        List<WatchThirdBpData> bpList = watchThirdBpDataMapper.queryByMonth(deviceId, monthStr);
-        if (bpList != null && !bpList.isEmpty()) {
-            flag = true;
-            return flag;
-        }
-        //血氧
-        List<WatchContinuousSpo2Data> spo2DataList = watchContinuousSpo2DataMapper.queryByMonth(deviceId, monthStr);
-        if (spo2DataList != null && !spo2DataList.isEmpty()) {
-            flag = true;
-            return flag;
-        }
-        //心率
-        List<WatchHeartRateData> hrList = watchHeartRateDataMapper.queryByMonth(deviceId, monthStr);
-        if (hrList != null && !hrList.isEmpty()) {
-            flag = true;
-            return flag;
-        }
-        //睡眠
-        List<WatchSleepData> sleepList = watchSleepDataMapper.queryByMonth(deviceId, monthStr);
-        if (sleepList != null && !sleepList.isEmpty()) {
-            flag = true;
-            return flag;
-        }
-        //血糖
-        List<WatchBloodGlucoseData> bgList = watchBloodGlucoseDataMapper.queryByMonth(deviceId, monthStr);
-        if (bgList != null && !bgList.isEmpty()) {
-            flag = true;
-            return flag;
+        if (deviceType == null ||  deviceType == 0) {
+            List<WatchThirdBpData> bpList = watchThirdBpDataMapper.queryByMonth(deviceId, monthStr);
+            if (bpList != null && !bpList.isEmpty()) {
+                flag = true;
+                return flag;
+            }
+            //血氧
+            List<WatchContinuousSpo2Data> spo2DataList = watchContinuousSpo2DataMapper.queryByMonth(deviceId, monthStr);
+            if (spo2DataList != null && !spo2DataList.isEmpty()) {
+                flag = true;
+                return flag;
+            }
+            //心率
+            List<WatchHeartRateData> hrList = watchHeartRateDataMapper.queryByMonth(deviceId, monthStr);
+            if (hrList != null && !hrList.isEmpty()) {
+                flag = true;
+                return flag;
+            }
+            //睡眠
+            List<WatchSleepData> sleepList = watchSleepDataMapper.queryByMonth(deviceId, monthStr);
+            if (sleepList != null && !sleepList.isEmpty()) {
+                flag = true;
+                return flag;
+            }
+            //血糖
+            List<WatchBloodGlucoseData> bgList = watchBloodGlucoseDataMapper.queryByMonth(deviceId, monthStr);
+            if (bgList != null && !bgList.isEmpty()) {
+                flag = true;
+                return flag;
+            }
+
+        } else {
+            List<FsThirdDeviceData> bpList = fsThirdDeviceDataMapper.queryByMonth(deviceId, monthStr,0);
+            if (bpList != null && !bpList.isEmpty()) {
+                flag = true;
+                return flag;
+            }
+            //血氧
+//            List<WatchContinuousSpo2Data> spo2DataList = fsThirdDeviceDataMapper.querySpo2ByMonth(deviceId, monthStr);
+//            if (spo2DataList != null && !spo2DataList.isEmpty()) {
+//                flag = true;
+//                return flag;
+//            }
+            //心率
+            List<FsThirdDeviceData> hrList = fsThirdDeviceDataMapper.queryByMonth(deviceId, monthStr,2);
+            if (hrList != null && !hrList.isEmpty()) {
+                flag = true;
+                return flag;
+            }
+            //睡眠
+//            List<WatchSleepData> sleepList = fsThirdDeviceDataMapper.querySleepByMonth(deviceId, monthStr);
+//            if (sleepList != null && !sleepList.isEmpty()) {
+//                flag = true;
+//                return flag;
+//            }
+            //血糖
+            List<FsThirdDeviceData> bgList = fsThirdDeviceDataMapper.queryByMonth(deviceId, monthStr,1);
+            if (bgList != null && !bgList.isEmpty()) {
+                flag = true;
+                return flag;
+            }
         }
         return flag;
     }
@@ -668,8 +866,8 @@ public class WatchDataServiceImpl implements WatchDataService {
             Integer status = uaData.getStatus();
             vo6.setData(uaData.getVal().toString());
             vo6.setStatus(WatchUaStatusEnum.toType(
-                    watchThirdUaDataService.getStatus(deviceId,uaData.getVal(),0L,0)
-            ).getDesc());
+                    watchThirdUaDataService.getStatus(deviceId,uaData.getVal()*10,0L,0)
+            ).getDesc()); //需根据性别判断新的 getLatest的结果是/10 所以此处应该*10
         } else {
             vo6.setDate("");
             vo6.setData("");

+ 0 - 79
fs-service/src/main/java/com/fs/watch/service/impl/WatchDeviceBeginnerGuideServiceImpl.java

@@ -1,79 +0,0 @@
-package com.fs.watch.service.impl;
-
-import com.alibaba.fastjson.JSONObject;
-import com.fs.common.config.WatchConfig;
-import com.fs.watch.domain.WatchDeviceBeginnerGuide;
-import com.fs.watch.service.WatchDeviceBeginnerGuideService;
-import com.fs.watch.utils.MyHttpUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-import java.util.*;
-
-@Service
-public class WatchDeviceBeginnerGuideServiceImpl implements WatchDeviceBeginnerGuideService {
-    @Autowired
-    private WatchConfig sysConfig;
-
-    private final static MyHttpUtils httpUtils = new MyHttpUtils();
-    /**
-     * 查询新手引导
-     *
-     * @param id 新手引导主键
-     * @return 新手引导
-     */
-    @Override
-    public WatchDeviceBeginnerGuide selectDeviceBeginnerGuideById(Long id)
-    {
-
-        WatchDeviceBeginnerGuide watchDeviceBeginnerGuide = null;
-        Map res = httpUtils.getRequest2(sysConfig.getWatchUrl(), "/watch/guide/" + id);
-        if (res!=null){
-            Object data = res.get("data");
-            if (data !=null){
-                watchDeviceBeginnerGuide = JSONObject.parseObject((String) data, WatchDeviceBeginnerGuide.class);
-            }
-        }
-        return watchDeviceBeginnerGuide;
-    }
-
-    /**
-     * 查询新手引导列表
-     *
-     * @param deviceBeginnerGuide 新手引导
-     * @return 新手引导
-     */
-    @Override
-    public List<WatchDeviceBeginnerGuide> selectDeviceBeginnerGuideList(WatchDeviceBeginnerGuide deviceBeginnerGuide)
-    {
-        List<WatchDeviceBeginnerGuide>  watchDeviceBeginnerGuides = new ArrayList<>();
-        Map rse = httpUtils.getRequest3(sysConfig.getWatchUrl(),
-                "/watch/guide/getList",
-                Objects.requireNonNull(getguideMap(deviceBeginnerGuide)));
-        if (rse!=null){
-            Object data = rse.get("data");
-            if (data !=null){
-                List list = JSONObject.parseObject(JSONObject.toJSONString(data), List.class);
-                if (list != null && !list.isEmpty()){
-                    for (Object o : list) {
-                        WatchDeviceBeginnerGuide guide = JSONObject.parseObject(JSONObject.toJSONString(o), WatchDeviceBeginnerGuide.class);
-                        watchDeviceBeginnerGuides.add(guide);
-                    }
-                }
-            }
-        }
-        return watchDeviceBeginnerGuides;
-    }
-
-    private Map<String, Object> getguideMap(WatchDeviceBeginnerGuide deviceBeginnerGuide) {
-        Map<String, Object> map = new HashMap<>();
-        map.put("id", deviceBeginnerGuide.getId());
-        map.put("title", deviceBeginnerGuide.getTitle());
-        map.put("url", deviceBeginnerGuide.getUrl());
-        map.put("type", deviceBeginnerGuide.getType());
-        map.put("isDel", deviceBeginnerGuide.getIsDel());
-        map.put("createTime", deviceBeginnerGuide.getCreateTime());
-        map.put("belong", deviceBeginnerGuide.getBelong());
-        return map;
-    }
-}

+ 0 - 4
fs-service/src/main/java/com/fs/watch/service/impl/WatchDeviceDataServiceImpl.java

@@ -35,10 +35,6 @@ public class WatchDeviceDataServiceImpl implements WatchDeviceDataService {
      */
     @Override
     public Boolean insert(WatchDeviceData watchDeviceData) {
-        Integer num = mapper.queryByCreateTime(watchDeviceData.getCreateTime());
-        if (num != null && num > 0) {
-            return false;
-        }
         try {
             mapper.insert(watchDeviceData);
         } catch (Exception e) {

+ 97 - 0
fs-service/src/main/java/com/fs/watch/service/impl/WatchDeviceInfoClicServiceImpl.java

@@ -4,6 +4,7 @@ import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.utils.StringUtils;
 import com.fs.watch.domain.IotSim;
 import com.fs.watch.domain.WatchDeviceInfoClic;
+import com.fs.watch.domain.vo.WatchDeviceInfoAndIotExportVO;
 import com.fs.watch.domain.vo.WatchDeviceInfoAndIotVo;
 import com.fs.watch.domain.vo.WatchDeviceInfoVo;
 import com.fs.watch.mapper.WatchDeviceInfoClicMapper;
@@ -18,8 +19,11 @@ import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.stream.Collectors;
 
 /**
  * 设备原始回传信息记录(WatchDeviceInfo)表服务实现类
@@ -166,4 +170,97 @@ public class WatchDeviceInfoClicServiceImpl implements WatchDeviceInfoClicServic
         return watchDeviceInfoClicMapper.selectDeviceInfoList(param);
     }
 
+    @Override
+    public List<WatchDeviceInfoAndIotExportVO> exportDeviceIdAndIotInfo(DeviceIdAndIotInfoQueryParam param) {
+
+        List<WatchDeviceInfoAndIotExportVO> resultList = new ArrayList<>();
+        int pageIndex = 1;
+        int pageSize = 1000;
+        while (true) {
+            //查询所有物联网卡
+            TableDataInfo tableDataInfo = IotUtils.querySIMTable(pageIndex, pageSize);
+            if (tableDataInfo != null) {
+                List<IotSim> iotSims = (List<IotSim>) tableDataInfo.getRows();
+                List<String> iccIds = iotSims.stream().map(x -> x.getIccid()).collect(Collectors.toList());
+                List<WatchDeviceInfoClic> watchDeviceInfoClics = watchDeviceInfoClicMapper.selectListByIccList(iccIds);
+                List<String> deviceIds = watchDeviceInfoClics.stream().map(m -> m.getDeviceId()).collect(Collectors.toList());
+                List<WatchDeviceInfoVo> watchDeviceInfos = deviceInfoService.selectCompanyNameByList(deviceIds);
+                Map<String, WatchDeviceInfoClic> mp = watchDeviceInfoClics.stream().filter(device -> device.getSim1Iccid() != null)
+                        .collect(Collectors.toMap(
+                                WatchDeviceInfoClic::getSim1Iccid,
+                                x -> x,
+                                (existing, replacement) -> existing
+                        ));
+                Map<Long, String> companyMp = watchDeviceInfos.stream().filter(x -> x.getDeviceId() != null && x.getCompanyName() != null).collect(Collectors.toMap(WatchDeviceInfoVo::getDeviceId, WatchDeviceInfoVo::getCompanyName));
+
+                //查询对应卡信息
+                if (iotSims != null && !iotSims.isEmpty()) {
+                    for (IotSim temp : iotSims) {
+                        WatchDeviceInfoAndIotExportVO addItem = new WatchDeviceInfoAndIotExportVO();
+                        BeanUtils.copyProperties(temp,addItem );
+                        if (mp.containsKey(addItem.getIccid())) {
+                            WatchDeviceInfoClic watchDeviceInfoClic = mp.get(addItem.getIccid());
+                            addItem.setDeviceId(watchDeviceInfoClic.getDeviceId());
+                            //查询公司名称
+                            if (companyMp.containsKey(watchDeviceInfoClic.getDeviceId())) {
+                                addItem.setCompanyName(companyMp.get(watchDeviceInfoClic.getDeviceId()));
+                            } else {
+                                addItem.setCompanyName(null);
+                            }
+                            if (watchDeviceInfoClic != null) {
+                                addItem.setDeviceId(watchDeviceInfoClic.getDeviceId());
+                                //查询公司名称
+                                WatchDeviceInfoVo deviceInfoVo = deviceInfoService.getByNumber(watchDeviceInfoClic.getDeviceId());
+                                addItem.setCompanyName(deviceInfoVo != null ? deviceInfoVo.getCompanyName() : null);
+                            }
+                        }
+
+                        switch(addItem.getCertified()){
+                            case 0:
+                                addItem.setCertifiedName("未认证");
+                                break;
+                            case 1:
+                                addItem.setCertifiedName("已认证");
+                                break;
+                            case 2:
+                                addItem.setCertifiedName("人工审核中");
+                                break;
+                            default:
+                                addItem.setCertifiedName("未知");
+                        }
+                        switch(addItem.getOperatorType()){
+                            case 1:
+                                addItem.setOperatorTypeName("移动");
+                                break;
+                            case 2:
+                                addItem.setOperatorTypeName("联通");
+                                break;
+                            case 3:
+                                addItem.setOperatorTypeName("电信");
+                                break;
+                            default:
+                                addItem.setOperatorTypeName("未知");
+                        }
+                        switch(addItem.getStatus()){
+                            case 5:
+                                addItem.setStatusName("已激活");
+                                break;
+                            case 6:
+                                addItem.setStatusName("已停用");
+                                break;
+                            default:
+                                addItem.setStatusName("未知");
+                        }
+                        resultList.add(addItem);
+                    }
+                }
+            }
+            if (tableDataInfo.getRows().size() < pageSize) {
+                break;
+            }
+            pageIndex++;
+        }
+        return resultList;
+    }
+
 }

+ 11 - 3
fs-service/src/main/java/com/fs/watch/service/impl/WatchDeviceInfoServiceImpl.java

@@ -18,7 +18,9 @@ import com.fs.watch.service.DeviceSetUpService;
 import com.fs.watch.service.WatchBasicInfoService;
 import com.fs.watch.service.WatchDataService;
 import com.fs.watch.service.WatchDeviceInfoService;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -30,6 +32,7 @@ import java.util.*;
  * @description 针对表【watch_device_info(设备硬件信息)】的数据库操作Service实现
  * @createDate 2024-10-15 11:06:50
  */
+@Slf4j
 @Service
 public class WatchDeviceInfoServiceImpl implements WatchDeviceInfoService {
     @Autowired
@@ -48,7 +51,7 @@ public class WatchDeviceInfoServiceImpl implements WatchDeviceInfoService {
 
     @Autowired
     private DeviceSetUpService deviceSetUpService;
-
+    @Lazy
     @Autowired
     private ICompanyService companyService;
     @Autowired
@@ -352,7 +355,7 @@ public class WatchDeviceInfoServiceImpl implements WatchDeviceInfoService {
         //电量 信号
         WatchBasicInfo info = watchBasicInfoService.queryLastByDeviceId(deviceNumber);
         if (info != null) {
-            System.out.println(info);
+            log.info("数据:{}", info);
             Map<String, Object> map = new HashMap<>();
             map.put("rssi", info.getRssi());
             map.put("device_id", deviceNumber);
@@ -470,7 +473,7 @@ public class WatchDeviceInfoServiceImpl implements WatchDeviceInfoService {
     private void queryCompanyUserInfo(WatchDeviceInfoVo watchDeviceInfoVo) {
         String companyUserId = watchDeviceInfoVo.getCompanyUserId();
         if (StringUtils.isNotBlank(companyUserId)) {
-            watchDeviceInfoVo.setCompanyUserName(companyUserService.selectCompanyUserByStrIds(companyUserId));
+            watchDeviceInfoVo.setCompanyUserName(companyUserService.selectCompanyUserByIds(companyUserId));
         }
     }
 
@@ -707,6 +710,11 @@ public class WatchDeviceInfoServiceImpl implements WatchDeviceInfoService {
         }
     }
 
+    @Override
+    public  List<WatchDeviceInfoVo> selectCompanyNameByList(List<String> deviceIds){
+        return mapper.selectCompanyNameByList(deviceIds);
+    }
+
     /**
      * 查询有设备编号的家人信息
      * @param str

+ 0 - 4
fs-service/src/main/java/com/fs/watch/service/impl/WatchDeviceStatusServiceImpl.java

@@ -33,10 +33,6 @@ public class WatchDeviceStatusServiceImpl implements WatchDeviceStatusService {
      */
     @Override
     public Boolean insert(WatchDeviceStatus watchDeviceStatus) {
-        Integer num = watchDeviceStatusMapper.queryByCreateTime(watchDeviceStatus.getEventtime());
-        if (num != null && num > 0) {
-            return false;
-        }
         try {
             watchDeviceStatusMapper.insert(watchDeviceStatus);
             //更新mysql的腕表数据

+ 20 - 0
fs-service/src/main/java/com/fs/watch/service/impl/WatchDeviceWeekServiceImpl.java

@@ -0,0 +1,20 @@
+package com.fs.watch.service.impl;
+
+import com.fs.watch.mapper.WatchDeviceWeekMapper;
+import com.fs.watch.service.WatchDeviceWeekService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+* @author Administrator
+* @description 针对表【watch_device_week(每周健康周报汇总)】的数据库操作Service实现
+* @createDate 2025-10-11 13:22:54
+*/
+@Service
+public class WatchDeviceWeekServiceImpl implements WatchDeviceWeekService {
+    @Autowired
+    private WatchDeviceWeekMapper watchDeviceWeekMapper;
+
+
+
+}

+ 0 - 4
fs-service/src/main/java/com/fs/watch/service/impl/WatchEcgDataServiceImpl.java

@@ -36,10 +36,6 @@ public class WatchEcgDataServiceImpl implements WatchEcgDataService {
 
     @Override
     public Boolean insert(WatchEcgData watchEcgData) {
-        Integer num = mapper.queryByCreateTime(watchEcgData.getCreateTime());
-        if (num != null && num > 0) {
-            return false;
-        }
         try {
             mapper.insert(watchEcgData);
         } catch (Exception e) {

+ 0 - 5
fs-service/src/main/java/com/fs/watch/service/impl/WatchFatigueDataServiceImpl.java

@@ -28,11 +28,6 @@ public class WatchFatigueDataServiceImpl implements WatchFatigueDataService {
 
     @Override
     public Boolean insert(WatchFatigueData watchFatigueData) {
-        //判断创建时间是否唯一
-        Integer num = mapper.queryByCreateTime(watchFatigueData.getCreateTime());
-        if (num != null && num > 0) {
-            return false;
-        }
         try {
             mapper.insert(watchFatigueData);
         } catch (Exception e) {

+ 46 - 14
fs-service/src/main/java/com/fs/watch/service/impl/WatchHeartRateDataServiceImpl.java

@@ -2,6 +2,8 @@ package com.fs.watch.service.impl;
 
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.StringUtils;
+import com.fs.his.domain.FsThirdDeviceData;
+import com.fs.his.mapper.FsThirdDeviceDataMapper;
 import com.fs.watch.domain.WatchDeviceInfo;
 import com.fs.watch.domain.WatchHeartRateData;
 import com.fs.watch.domain.vo.WatchHeartRateDataVo;
@@ -27,15 +29,11 @@ public class WatchHeartRateDataServiceImpl implements WatchHeartRateDataService
     private WatchHeartRateDataMapper mapper;
     @Autowired
     private WatchDeviceInfoMapper watchDeviceInfoMapper;
+    @Autowired
+    private FsThirdDeviceDataMapper fsThirdDeviceDataMapper;
 
     @Override
     public Boolean insert(WatchHeartRateData watchHeartRateData) {
-        //判断创建时间是否唯一
-        Integer num = mapper.queryByCreateTime(watchHeartRateData.getCreateTime());
-        if (num != null && num > 0) {
-            log.error("===============watchHeartRateData:insert:num=========================={}", num);
-            return false;
-        }
         try {
             mapper.insert(watchHeartRateData);
         } catch (Exception e) {
@@ -76,7 +74,7 @@ public class WatchHeartRateDataServiceImpl implements WatchHeartRateDataService
         Integer max = 0;
         Integer min = 0;
         Integer avg = 0;
-        if (list.size() > 0) {
+        if (!list.isEmpty()) {
             max = list.stream().max(Comparator.comparingInt(WatchHeartRateData::getMaxBpm)).get().getMaxBpm();
             min = list.stream().min(Comparator.comparingInt(WatchHeartRateData::getMinBpm)).get().getMinBpm();
             //计算平均值
@@ -96,11 +94,29 @@ public class WatchHeartRateDataServiceImpl implements WatchHeartRateDataService
     }
 
     @Override
-    public WatchHeartRateDataVo list(Date startTime, Date endTime, String deviceId) {
+    public WatchHeartRateDataVo list(Date startTime, Date endTime, String deviceId, Integer deviceType) {
         if (StringUtils.isNotBlank(deviceId)) {
-            List<WatchHeartRateData> data = mapper.list(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
-                    DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),
-                    deviceId);
+            List<WatchHeartRateData> data = new ArrayList<>();
+            if (deviceType == null || deviceType == 0){
+                data = mapper.list(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
+                        DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),
+                        deviceId);
+
+            } else {
+                List<FsThirdDeviceData> list = fsThirdDeviceDataMapper.selectListByDateAndDeviceIdAndRecordType(startTime, endTime, deviceId, 2, null);
+                if (list != null && !list.isEmpty()) {
+                    for (FsThirdDeviceData item : list) {
+                        WatchHeartRateData watchHeartRateData = new WatchHeartRateData();
+                        watchHeartRateData.setDeviceId(item.getDeviceId());
+                        watchHeartRateData.setMaxBpm(Integer.valueOf(item.getRecordValue()));
+                        watchHeartRateData.setMinBpm(Integer.valueOf(item.getRecordValue()));
+                        watchHeartRateData.setAvgBpm(Integer.valueOf(item.getRecordValue()));
+                        watchHeartRateData.setCreateTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",item.getCreateTime()));
+                        watchHeartRateData.setStatus(item.getStatus());
+                        data.add(watchHeartRateData);
+                    }
+                }
+            }
             return getWatchHeartRateDataVo(data);
         }
         return null;
@@ -132,15 +148,31 @@ public class WatchHeartRateDataServiceImpl implements WatchHeartRateDataService
 
 
     @Override
-    public List<Map<String, Object>> countHeartByDate(Date startTime, Date endTime, String deviceId) {
+    public List<Map<String, Object>> countHeartByDate(Date startTime, Date endTime, String deviceId,Integer deviceType) {
         if (StringUtils.isBlank(deviceId)) {
             return null;
         }
         //返回对象
         List<Map<String, Object>> res = null;
-        res = mapper.countBpByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
-                DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime), deviceId);
+        if (deviceType == null || deviceType == 0){
+            res = mapper.countBpByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
+                    DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime), deviceId);
+        } else {
+            res = fsThirdDeviceDataMapper.countByDateAndDeviceIdAndRecordType(startTime, endTime, deviceId, 2, null);
+        }
+
 
         return res;
     }
+
+    @Override
+    public Integer getStatus(int maxBpm, int minBpm) {
+        if (maxBpm > 100) {
+            return WatchHrStatusEnum.FAST.getValue();
+        } else if (minBpm < 60) {
+            return WatchHrStatusEnum.LOW.getValue();
+        } else {
+            return WatchHrStatusEnum.NORMAL.getValue();
+        }
+    }
 }

+ 0 - 5
fs-service/src/main/java/com/fs/watch/service/impl/WatchMultiLeadsEcgDataServiceImpl.java

@@ -21,11 +21,6 @@ public class WatchMultiLeadsEcgDataServiceImpl implements WatchMultiLeadsEcgData
 
     @Override
     public Boolean insert(WatchMultiLeadsEcgData watchMultiLeadsEcgData) {
-        //判断创建时间是否唯一
-        Integer num = mapper.queryByCreateTime(watchMultiLeadsEcgData.getCreateTime());
-        if (num != null && num > 0) {
-            return false;
-        }
         try {
             mapper.insert(watchMultiLeadsEcgData);
         } catch (Exception e) {

+ 0 - 5
fs-service/src/main/java/com/fs/watch/service/impl/WatchPpgDataServiceImpl.java

@@ -20,11 +20,6 @@ public class WatchPpgDataServiceImpl implements WatchPpgDataService {
 
     @Override
     public Boolean insert(WatchPpgData watchPpgData) {
-        //判断创建时间是否唯一
-        Integer num = mapper.queryByCreateTime(watchPpgData.getCreateTime());
-        if (num != null && num > 0) {
-            return false;
-        }
         try {
             mapper.insert(watchPpgData);
         } catch (Exception e) {

+ 15 - 15
fs-service/src/main/java/com/fs/watch/service/impl/WatchRriDataServiceImpl.java

@@ -45,11 +45,6 @@ public class WatchRriDataServiceImpl implements WatchRriDataService {
 
     @Override
     public Boolean insert(WatchRriData watchRriData) {
-        //判断创建时间是否唯一
-        Integer num = mapper.queryByCreateTime(watchRriData.getCreateTime());
-        if (num != null && num > 0) {
-            return false;
-        }
         try {
             mapper.insert(watchRriData);
         } catch (Exception e) {
@@ -97,17 +92,22 @@ public class WatchRriDataServiceImpl implements WatchRriDataService {
         //2.2发送请求
         Map resData = httpUtils.getPost2("https://api1.iwown.com/algoservice", "/calculation/af", param);
 
-        if (resData == null) {
-            param.put("account", watchConfig.getAccount2());
-            param.put("password", watchConfig.getPassword2());
-            resData = httpUtils.getPost2("https://api1.iwown.com/algoservice", "/calculation/af", param);
-            if (resData == null) {
-                param.put("account", watchConfig.getAccount3());
-                param.put("password", watchConfig.getPassword3());
+        if (resData != null && "the device_id not belong to you".equals(resData.get("message"))) {
+            if ("the device_id not belong to you".equals(resData.get("message"))){
+                param.put("account", watchConfig.getAccount2());
+                param.put("password", watchConfig.getPassword2());
                 resData = httpUtils.getPost2("https://api1.iwown.com/algoservice", "/calculation/af", param);
+                if (resData != null && "the device_id not belong to you".equals(resData.get("message"))) {
+                    if ("the device_id not belong to you".equals(resData.get("message"))){
+                        param.put("account", watchConfig.getAccount3());
+                        param.put("password", watchConfig.getPassword3());
+                        resData = httpUtils.getPost2("https://api1.iwown.com/algoservice", "/calculation/af", param);
+                    }
+                }
             }
+
         }
-        if (resData != null) {
+        if (resData != null && !"the device_id not belong to you".equals(resData.get("message"))) {
             /**
              * 0 无结果, 有干扰或者数据异常
              * 1 窦性心率
@@ -199,11 +199,11 @@ public class WatchRriDataServiceImpl implements WatchRriDataService {
             Map resData = null;
             if (!params.isEmpty()) {
                 resData = httpUtils.getPost2("https://api1.iwown.com/algoservice", "/calculation/af", param);
-                if (resData == null) {
+                if (resData != null && "the device_id not belong to you".equals(resData.get("message"))) {
                     param.put("account", watchConfig.getAccount2());
                     param.put("password", watchConfig.getPassword2());
                     resData = httpUtils.getPost2("https://api1.iwown.com/algoservice", "/calculation/af", param);
-                    if (resData == null) {
+                    if (resData != null && "the device_id not belong to you".equals(resData.get("message"))) {
                         param.put("account", watchConfig.getAccount3());
                         param.put("password", watchConfig.getPassword3());
                         resData = httpUtils.getPost2("https://api1.iwown.com/algoservice", "/calculation/af", param);

+ 152 - 63
fs-service/src/main/java/com/fs/watch/service/impl/WatchSleepDataServiceImpl.java

@@ -5,7 +5,10 @@ import com.alibaba.fastjson.JSONObject;
 import com.fs.common.config.WatchConfig;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.StringUtils;
+import com.fs.his.domain.FsThirdDeviceData;
+import com.fs.his.mapper.FsThirdDeviceDataMapper;
 import com.fs.watch.calculation.SleepPreprocessor;
+import com.fs.watch.calculation.SleepScoreCalculator;
 import com.fs.watch.domain.*;
 import com.fs.watch.domain.vo.AppWatchSleepDataVo;
 import com.fs.watch.domain.vo.WatchSleepDataVo;
@@ -17,6 +20,7 @@ import com.fs.watch.service.WatchRriDataService;
 import com.fs.watch.service.WatchSleepDataService;
 import com.fs.watch.utils.MyHttpUtils;
 import lombok.extern.slf4j.Slf4j;
+import org.jetbrains.annotations.NotNull;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 import org.springframework.stereotype.Service;
@@ -26,6 +30,7 @@ import java.text.SimpleDateFormat;
 import java.time.Duration;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeParseException;
 import java.util.*;
@@ -55,16 +60,14 @@ public class WatchSleepDataServiceImpl implements WatchSleepDataService {
     @Autowired
     private ThreadPoolTaskExecutor threadPoolTaskExecutor;
 
+    @Autowired
+    private FsThirdDeviceDataMapper fsThirdDeviceDataMapper;
+
 
     private static final MyHttpUtils httpUtils = new MyHttpUtils();
 
     @Override
     public Boolean insert(WatchSleepData watchSleepData) {
-        //判断创建时间是否唯一
-        Integer num = mapper.queryByCreateTime(watchSleepData.getCreateTime());
-        if (num != null && num > 0) {
-            return false;
-        }
         try {
             mapper.insert(watchSleepData);
         } catch (Exception e) {
@@ -154,52 +157,69 @@ public class WatchSleepDataServiceImpl implements WatchSleepDataService {
             String password = null;
             //获取账号密码
             WatchDeviceAccount deviceAccount = watchDeviceAccountMapper.selectWatchDeviceAccountByDeviceId(deviceId);
-            boolean flag = true;
+            boolean flag = false;
             if(deviceAccount!=null){
                 account = deviceAccount.getAccount();
                 password = deviceAccount.getPassword();
-                tryPostGetSleep(param,account,password,list,vo);
+                Boolean tryRequest = tryPostGetSleep(param, account, password, list, vo);
+                flag = tryRequest == null ?true:tryRequest;
             } else {
+                flag = true;
+            }
+            if (!flag) {
                 account = watchConfig.getAccount1();
                 password = watchConfig.getPassword1();
-                flag = tryPostGetSleep(param, account, password, list, vo);
+                flag = tryPostGetSleep(param, account, password, list, vo) != null;
                 if (!flag){
-                    flag = tryPostGetSleep(param, account, password, list, vo);
+                    flag = tryPostGetSleep(param, account, password, list, vo) != null;
                     if (!flag){
                         account = watchConfig.getAccount2();
                         password = watchConfig.getPassword2();
-                        flag = tryPostGetSleep(param, account, password, list, vo);
+                        flag = tryPostGetSleep(param, account, password, list, vo) != null;
                         if (!flag){
                             account = watchConfig.getAccount3();
                             password = watchConfig.getPassword3();
-                            tryPostGetSleep(param, account, password, list, vo);
+                            flag = tryPostGetSleep(param, account, password, list, vo) != null;
                         }
                     }
                 }
-                //存储账号密码
-                WatchDeviceAccount insertAccountTemp = new WatchDeviceAccount();
-                insertAccountTemp.setDeviceId(deviceId);
-                insertAccountTemp.setAccount(account);
-                insertAccountTemp.setPassword(password);
-                watchDeviceAccountMapper.insertWatchDeviceAccount(insertAccountTemp);
+                if (flag){
+                    //存储账号密码
+                    WatchDeviceAccount insertAccountTemp = new WatchDeviceAccount();
+                    insertAccountTemp.setDeviceId(deviceId);
+                    insertAccountTemp.setAccount(account);
+                    insertAccountTemp.setPassword(password);
+                    if (deviceAccount.getId() != null){
+                        insertAccountTemp.setId(deviceAccount.getId());
+                        watchDeviceAccountMapper.updateWatchDeviceAccount(insertAccountTemp);
+                    } else {
+                        watchDeviceAccountMapper.insertWatchDeviceAccount(insertAccountTemp);
+
+                    }
+
+                }
             }
+
             //存到每日情况
             if (vo.getScore() != null && vo.getScore() > 0) {
-                //查询是否存在
-                WatchDeviceDay dayInfo = new WatchDeviceDay();
-                dayInfo.setSleepScore(vo.getScore());
-                dayInfo.setSleepDetail(JSONObject.toJSONString(vo));
-                //dayInfo.setSleepStatus(getSleepEnum().getValue());
-                if (oldInfo != null) {
-                    dayInfo.setId(oldInfo.getId());
-                    watchDeviceDayMapper.updateWatchDeviceDay(dayInfo);
-                } else {
+                //10.11 优化->存今天以前的数据,防止一天的睡眠数据还在变动
+                // 获取今天的 00:00:00
+                LocalDateTime todayStart = LocalDate.now().atStartOfDay();
+                // 将 Date 转换为 LocalDateTime
+                LocalDateTime createDateTime = createTime.toInstant()
+                        .atZone(ZoneId.systemDefault())
+                        .toLocalDateTime();
+
+                if (createDateTime.isBefore(todayStart)) {
+                    //查询是否存在
+                    WatchDeviceDay dayInfo = new WatchDeviceDay();
+                    dayInfo.setSleepScore(vo.getScore());
+                    dayInfo.setSleepDetail(JSONObject.toJSONString(vo));
+                    //dayInfo.setSleepStatus(getSleepEnum().getValue());
                     dayInfo.setDeviceId(deviceId);
                     dayInfo.setCreateTime(createTime);
                     watchDeviceDayMapper.insertWatchDeviceDay(dayInfo);
                 }
-
-
             }
         }
 
@@ -207,20 +227,30 @@ public class WatchSleepDataServiceImpl implements WatchSleepDataService {
         return vo;
     }
 
-    private boolean tryPostGetSleep(HashMap<String, Object> param,String account,String password,List<SleepSection> list,WatchSleepDataVo vo){
+    private Boolean tryPostGetSleep(HashMap<String, Object> param,String account,String password,List<SleepSection> list,WatchSleepDataVo vo){
         param.put("account",account);
         param.put("password",password);
         Map resData = httpUtils.getPost2("https://api1.iwown.com/algoservice", "/calculation/sleep", param);
         if (resData != null) {
+            if (resData.get("message") != null){
+                if ("the device_id not belong to you".equals(resData.get("message").toString())){
+                    return null;
+                }
+            }
             String startTime = resData.get("start_time").toString();
             String endTime = resData.get("end_time").toString();
             list = JSONObject.parseArray(JSONObject.toJSONString(resData.get("sections")), SleepSection.class);
             vo.setSleepSection(list);
+            AppWatchSleepDataVo appWatchSleepDataVo = parserResult(vo.getDeviceId(), vo);
+            vo.setSleepTime(appWatchSleepDataVo.getSleepTime());
+            vo.setLightSleep(appWatchSleepDataVo.getLightSleep());
+            vo.setEyemoveSleep(appWatchSleepDataVo.getEyemoveSleep());
+            vo.setWeakSleep(appWatchSleepDataVo.getWeakSleep());
             vo.setStartTime(startTime);
             vo.setEndTime(endTime);
             vo.setScore(Integer.parseInt(resData.get("score").toString()));
             return true;
-        } else {
+        }  else {
             return false;
         }
     }
@@ -261,7 +291,7 @@ public class WatchSleepDataServiceImpl implements WatchSleepDataService {
     }
 
     @Override
-    public AppWatchSleepDataVo list(Date startTime, Date endTime, String deviceId) {
+    public AppWatchSleepDataVo list(Date startTime, Date endTime, String deviceId, Integer deviceType) {
         //返回对象
         AppWatchSleepDataVo vo = new AppWatchSleepDataVo();
         // 使用 Calendar 类来循环增加日期
@@ -283,33 +313,76 @@ public class WatchSleepDataServiceImpl implements WatchSleepDataService {
         //夜间睡眠时间(深睡+浅睡)
         Integer sleepCount=0;
         long timeTotal = 0L; //睡眠总时间
-
+        List<WatchSleepDataVo> watchSleepDataVos = new ArrayList<>();
         while (calendar.getTime().before(endTime) || calendar.getTime().equals(endTime)) {
             Date currentDate = calendar.getTime();
-//                System.out.println(currentDate);
-            WatchSleepDataVo watchSleepDataVo = getSleepSection(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, currentDate), deviceId);
-            if (watchSleepDataVo != null && watchSleepDataVo.getSleepSection() !=null && watchSleepDataVo.getSleepSection().size() > 0) {
-                AppWatchSleepDataVo appWatchSleepDataVo = parserResult(deviceId, watchSleepDataVo);
-                //统计图对象
-                sleepSection.addAll(appWatchSleepDataVo.getSleepSection());
-                //深睡时间
-                sSleep = sSleep + appWatchSleepDataVo.getDeepSleep();
-                //浅睡时间
-                lightSleep =lightSleep+ appWatchSleepDataVo.getLightSleep();
-                //清醒时间
-                weakSleep =weakSleep+ appWatchSleepDataVo.getWeakSleep();
-                //快速眼动时间
-                eyemoveSleep =eyemoveSleep+ appWatchSleepDataVo.getEyemoveSleep();
-                //清醒次数
-                weakTime = weakTime + appWatchSleepDataVo.getWeakTime();
-                //夜间睡眠时间(深睡+浅睡)
-                sleepCount=sleepCount+appWatchSleepDataVo.getSleepCount();
-
-                timeTotal = timeTotal + appWatchSleepDataVo.getSleepTime();
-
-                //呼吸质量 得分(百分制)
+            if (deviceType == null || deviceType == 0) {
+//                log.info(currentDate);
+                WatchSleepDataVo watchSleepDataVo = getSleepSection(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, currentDate), deviceId);
+                if (watchSleepDataVo != null && watchSleepDataVo.getSleepSection() !=null && !watchSleepDataVo.getSleepSection().isEmpty()) {
+                    watchSleepDataVo.setDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, currentDate));
+                    watchSleepDataVos.add(watchSleepDataVo);
+                    AppWatchSleepDataVo appWatchSleepDataVo = parserResult(deviceId, watchSleepDataVo);
+                    //统计图对象
+                    sleepSection.addAll(appWatchSleepDataVo.getSleepSection());
+                    //深睡时间
+                    sSleep = sSleep + appWatchSleepDataVo.getDeepSleep();
+                    //浅睡时间
+                    lightSleep =lightSleep+ appWatchSleepDataVo.getLightSleep();
+                    //清醒时间
+                    weakSleep =weakSleep+ appWatchSleepDataVo.getWeakSleep();
+                    //快速眼动时间
+                    eyemoveSleep =eyemoveSleep+ appWatchSleepDataVo.getEyemoveSleep();
+                    //清醒次数
+                    weakTime = weakTime + appWatchSleepDataVo.getWeakTime();
+                    //夜间睡眠时间(深睡+浅睡)
+                    sleepCount=sleepCount+appWatchSleepDataVo.getSleepCount();
+
+                    timeTotal = timeTotal + appWatchSleepDataVo.getSleepTime();
+
+                }
+            } else {
+                Date dayStartTime = DateUtils.truncate(currentDate, Calendar.DATE);
+                Date dayEndTime =  DateUtils.addMilliseconds(
+                        DateUtils.addDays(DateUtils.truncate(currentDate, Calendar.DATE), 1),
+                        -1
+                );
+                List<FsThirdDeviceData> list = fsThirdDeviceDataMapper.selectListByDateAndDeviceIdAndRecordType(dayStartTime, dayEndTime, deviceId, 7, null);
+                if (list != null && !list.isEmpty()) {
+                    SleepStatistics sleepStatistics = SleepScoreCalculator.calculateDetailedStatistics(list);
+                    List<SleepSection> sleepSection1 = sleepStatistics.getSleepSection();
+                    //统计图对象
+                    sleepSection.addAll(sleepSection1);
+                    //深睡时间
+                    sSleep = sSleep + sleepStatistics.getDeepSleepHours().longValue()*60;
+                    //浅睡时间
+                    lightSleep =lightSleep+ sleepStatistics.getLightSleepHours().longValue()*60;
+                    //清醒时间
+                    weakSleep = (long) (weakSleep+ (sleepStatistics.getAwakeDuration() / (1000.0 * 60)));
+                    //没有快速眼动时间
+                    //清醒次数
+                    weakTime = weakTime + sleepStatistics.getAwakeCount();
+                    //夜间睡眠时间(深睡+浅睡)
+                    sleepCount=sleepCount+(sleepStatistics.getDeepSleepCount() + sleepStatistics.getLightSleepCount());
+
+                    timeTotal = timeTotal + sleepStatistics.getTotalSleepHours().longValue()*60;
+                    WatchSleepDataVo watchSleepDataVo = new WatchSleepDataVo();
+                    watchSleepDataVo.setDeviceId(deviceId);
+                    watchSleepDataVo.setDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, currentDate));
+                    watchSleepDataVo.setStartTime(sleepSection1.get(0).getStart());
+                    watchSleepDataVo.setEndTime(sleepSection1.get(sleepSection1.size()-1).getEnd());
+                    watchSleepDataVo.setDeepSleep(sleepStatistics.getDeepSleepHours().intValue() * 60);
+                    watchSleepDataVo.setLightSleep(sleepStatistics.getLightSleepHours().intValue() * 60);
+                    watchSleepDataVo.setWeakSleep((int) (sleepStatistics.getAwakeDuration() / (1000.0 * 60)));
+                    watchSleepDataVo.setEyemoveSleep(sleepStatistics.getRemHours().intValue() * 60);
+//                    watchSleepDataVo.setScore(score); // 需要从某处获取睡眠得分
+                    watchSleepDataVo.setSleepTime(sleepStatistics.getTotalSleepHours().intValue() * 60);
+                    watchSleepDataVo.setSleepSection(sleepSection1);
+                    watchSleepDataVos.add(watchSleepDataVo);
+                }
             }
 
+
             // 增加一天
             calendar.add(Calendar.DAY_OF_MONTH, 1);
         }
@@ -322,6 +395,7 @@ public class WatchSleepDataServiceImpl implements WatchSleepDataService {
         vo.setWeakTime(weakTime);
         vo.setSleepCount(sleepCount);
         vo.setSleepTime((int)timeTotal);
+        vo.setWatchSleepDataVoList(watchSleepDataVos);
 
         if (timeTotal == 0){
             vo.setDeepScale(0);
@@ -455,7 +529,7 @@ public class WatchSleepDataServiceImpl implements WatchSleepDataService {
         DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
 
 
-        if (list != null && list.size() > 0) {
+        if (list != null && !list.isEmpty()) {
             for (SleepSection sleepSection : list) {
                 /**
                  * {
@@ -466,8 +540,11 @@ public class WatchSleepDataServiceImpl implements WatchSleepDataService {
                  */
 
                 // 解析字符串为 LocalDateTime 对象
-                LocalDateTime start = LocalDateTime.parse(sleepSection.getStart(), formatter);
-                LocalDateTime end = LocalDateTime.parse(sleepSection.getEnd(), formatter);
+
+                String startSleep = getTimeString(sleepSection.getStart());
+                String endSleep = getTimeString(sleepSection.getEnd());
+                LocalDateTime start = LocalDateTime.parse(startSleep, formatter);
+                LocalDateTime end = LocalDateTime.parse(endSleep, formatter);
 
                 // 计算时间差(以分钟为单位)
                 long minutes = Duration.between(start, end).toMinutes();
@@ -508,12 +585,12 @@ public class WatchSleepDataServiceImpl implements WatchSleepDataService {
             vo.setSleepTime(timeTotal.intValue());
             vo.setSleepSection(list);
             Integer score = watchSleepDataVo.getScore();
-            if (score ==null || score ==0){
-                //计算睡眠得分
-                vo.setScore(calculateSleepScore(iCount, vo));
-            } else {
-                vo.setScore(score);
-            }
+//            if (score ==null || score ==0){
+//                //计算睡眠得分
+//                vo.setScore(calculateSleepScore(iCount, vo));
+//            } else {
+            vo.setScore(score);
+//            }
             //深睡比例 28%
             vo.setDeepScale((int) (sTime * 100 / timeTotal));
             //浅睡比例 46%
@@ -525,6 +602,18 @@ public class WatchSleepDataServiceImpl implements WatchSleepDataService {
         return vo;
     }
 
+    private static @NotNull String getTimeString(String startSleep) {
+        if (startSleep == null) {
+            return "";
+        }
+
+        // 使用正则表达式匹配并替换负数情况
+        // 直接将":-数字"替换为":00"
+        String result = startSleep.replaceAll(":-\\d+", ":00");
+
+        return result;
+    }
+
     private static int calculateDeepSleepScore(Long sTime) {
         int MAX_SLEEP_HOURS = 6;
         // 满分标准为8小时深睡

+ 72 - 0
fs-service/src/main/java/com/fs/watch/service/impl/WatchSosCallLogsServiceImpl.java

@@ -0,0 +1,72 @@
+package com.fs.watch.service.impl;
+
+import com.fs.watch.domain.WatchSosCallLogs;
+import com.fs.watch.mapper.WatchSosCallLogsMapper;
+import com.fs.watch.service.WatchSosCallLogsService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * sos报警日志(WatchSosCallLogs)表服务实现类
+ *
+ * @author makejava
+ * @since 2024-12-24 14:30:26
+ */
+@Service("watchSosCallLogsService")
+@Slf4j
+public class WatchSosCallLogsServiceImpl implements WatchSosCallLogsService {
+    @Autowired
+    private WatchSosCallLogsMapper mapper;
+
+
+
+
+    /**
+     * 新增数据
+     *
+     * @param data 实例对象
+     * @return 实例对象
+     */
+    @Override
+    public Boolean insert(WatchSosCallLogs data) {
+        try {
+            mapper.insert(data);
+        } catch (Exception e) {
+            log.error("===============watchSosCall:insert=========================={}", e.getMessage());
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public Boolean batchInsertData(List<WatchSosCallLogs> list) {
+        try {
+            if (list.size() > 0) {
+                mapper.batchInsertData(list);
+
+            }
+        } catch (Exception e) {
+            log.error("===============watchSosCall:insert=========================={}", e.getMessage());
+            return false;
+        }
+        return true;
+    }
+
+    private Map<String, Object> getSosCallMap(WatchSosCallLogs data) {
+        Map<String, Object> params = new HashMap<>();
+        params.put("id", data.getId());
+        params.put("deviceId", data.getDeviceId());
+        params.put("alarmTime", data.getAlarmTime());
+        params.put("lat", data.getLat());
+        params.put("lon", data.getLon());
+        params.put("callLogs", data.getCallLogs());
+        return params;
+    }
+
+}

+ 68 - 28
fs-service/src/main/java/com/fs/watch/service/impl/WatchSpo2DataServiceImpl.java

@@ -2,6 +2,8 @@ package com.fs.watch.service.impl;
 
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.StringUtils;
+import com.fs.his.domain.FsThirdDeviceData;
+import com.fs.his.mapper.FsThirdDeviceDataMapper;
 import com.fs.watch.domain.WatchContinuousSpo2Data;
 import com.fs.watch.domain.WatchDeviceInfo;
 import com.fs.watch.domain.WatchSpo2Data;
@@ -35,14 +37,12 @@ public class WatchSpo2DataServiceImpl implements WatchSpo2DataService {
     @Autowired
     private WatchDeviceInfoMapper watchDeviceInfoMapper;
 
+    @Autowired
+    private FsThirdDeviceDataMapper fsThirdDeviceDataMapper;
+
 
     @Override
     public Boolean insert(WatchSpo2Data watchSpo2Data) {
-        //判断创建时间是否唯一
-        Integer num = mapper.queryByCreateTime(watchSpo2Data.getCreateTime());
-        if (num != null && num > 0) {
-            return false;
-        }
         try {
             mapper.insert(watchSpo2Data);
         } catch (Exception e) {
@@ -71,41 +71,76 @@ public class WatchSpo2DataServiceImpl implements WatchSpo2DataService {
     }
 
     @Override
-    public WatchSpo2DataQueryVo querySpByDate(Date startTime, Date endTime, String deviceId) {
+    public WatchSpo2DataQueryVo querySpByDate(Date startTime, Date endTime, String deviceId,Integer deviceType) {
         if (StringUtils.isNotBlank(deviceId)) {
-            List<WatchSpo2DataVo> spo2DataVos = mapper.querySpByDate(DateUtils.parseDateToStr(
-                    DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
-                    DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),
-                    deviceId);
+            WatchSpo2DataQueryVo watchSpo2DataQueryVo = new WatchSpo2DataQueryVo();
+            if (deviceType == null || deviceType == 0){
+                List<WatchSpo2DataVo> spo2DataVos = mapper.querySpByDate(DateUtils.parseDateToStr(
+                                DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
+                        DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),
+                        deviceId);
 //            List<WatchContinuousSpo2Data> datas = continuousSpo2DataService.querySpByDate(DateUtils.parseDateToStr(
 //                    DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
 //                    DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),
 //                    deviceId);
 //            //数据处理
 //            ArrayList<WatchSpo2DataVo> spo2DataVos = getWatchSpo2DataVos(deviceId, datas);
-            WatchSpo2DataQueryVo watchSpo2DataQueryVo = new WatchSpo2DataQueryVo();
-            watchSpo2DataQueryVo.setList(spo2DataVos);
-            Integer max = 0;
-            Integer min = 0;
-            double avg = 0.;
+                watchSpo2DataQueryVo.setList(spo2DataVos);
+                Integer max = 0;
+                Integer min = 0;
+                double avg = 0.;
 //
-            if (!spo2DataVos.isEmpty()){
-                max = spo2DataVos.stream().map(WatchSpo2DataVo::getMaxBoxy).max(Integer::compareTo).get();
-                min = spo2DataVos.stream().map(WatchSpo2DataVo::getMinBoxy).min(Integer::compareTo).get();
-                avg = spo2DataVos.stream().map(WatchSpo2DataVo::getAvgBoxy).min(Double::compareTo).get();
+                if (!spo2DataVos.isEmpty()){
+                    max = spo2DataVos.stream().map(WatchSpo2DataVo::getMaxBoxy).max(Integer::compareTo).get();
+                    min = spo2DataVos.stream().map(WatchSpo2DataVo::getMinBoxy).min(Integer::compareTo).get();
+                    avg = spo2DataVos.stream().map(WatchSpo2DataVo::getAvgBoxy).min(Double::compareTo).get();
 //                OptionalDouble  averageValue = spo2DataVos.stream().filter(temp->temp.getAvgBoxy()!=null).mapToDouble(WatchSpo2DataVo::getAvgBoxy)
 //                        .average();
-                // 如果平均值存在,将其转换为 int 类型并输出
+                    // 如果平均值存在,将其转换为 int 类型并输出
 //                if (averageValue.isPresent()) {
 ////                    avg = (int) averageValue.getAsDouble();  // 将 double 转换为 int
 //                    avg = averageValue.getAsDouble();  // 将 double 转换为 int
 //                    avg = Math.round(avg * 100.0) / 100.0;
 //                }
-            }
+                }
+
+                watchSpo2DataQueryVo.setMax(max);
+                watchSpo2DataQueryVo.setMin(min);
+                watchSpo2DataQueryVo.setAvg(avg);
 
-            watchSpo2DataQueryVo.setMax(max);
-            watchSpo2DataQueryVo.setMin(min);
-            watchSpo2DataQueryVo.setAvg(avg);
+            } else {
+                List<FsThirdDeviceData> list = fsThirdDeviceDataMapper.selectListByDateAndDeviceIdAndRecordType(startTime,endTime,deviceId,4,null);
+                if (list != null && !list.isEmpty()) {
+                    int max = 0;
+                    int min = 0;
+                    double avg = 0.;
+                    int sum = 0;
+                    List<WatchSpo2DataVo> listVos = new ArrayList<>();
+                    for (FsThirdDeviceData fsThirdDeviceData : list) {
+                        WatchSpo2DataVo vo = new WatchSpo2DataVo();
+                        vo.setDeviceId(fsThirdDeviceData.getDeviceId());
+                        int num = Integer.parseInt(fsThirdDeviceData.getRecordValue());
+                        vo.setMinBoxy(num);
+                        vo.setMaxBoxy(num);
+                        vo.setAvgBoxy(Double.valueOf(num));
+                        vo.setStatus(getStatus(num,num));
+                        listVos.add(vo);
+                        max = Math.max(num, max);
+                        min = Math.min(num, min);
+                        sum += num;
+                    }
+                    if (sum > 0){
+                        avg = (double) sum / listVos.size();
+                    }
+                    watchSpo2DataQueryVo.setMin(min);
+                    watchSpo2DataQueryVo.setMax(max);
+                    watchSpo2DataQueryVo.setAvg(avg);
+                    watchSpo2DataQueryVo.setList(listVos);
+                } else {
+                    return null;
+                }
+
+            }
             return watchSpo2DataQueryVo;
         }
         return null;
@@ -173,20 +208,25 @@ public class WatchSpo2DataServiceImpl implements WatchSpo2DataService {
     }
 
     @Override
-    public List<Map<String, Object>> countSpByDate(Date startTime, Date endTime, String deviceId) {
+    public List<Map<String, Object>> countSpByDate(Date startTime, Date endTime, String deviceId,Integer deviceType) {
         if (StringUtils.isBlank(deviceId)) {
             return null;
         }
-//        res = mapper.countSpByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
+        if (deviceType == null || deviceType == 0) {
+            //        res = mapper.countSpByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
 //                DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),deviceId);
-        return mapper.countSpByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
-                DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),deviceId);
+            return mapper.countSpByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
+                    DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),deviceId);
 //        List<WatchContinuousSpo2Data> list = continuousSpo2DataService.querySpByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
 //                DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime), deviceId);
 //        if (list != null && list.size() > 0) {
 //            return getStatusCount(list);
 //        }
 //        return null;
+        } else {
+           return fsThirdDeviceDataMapper.countByDateAndDeviceIdAndRecordType(startTime, endTime, deviceId, 4,null);
+        }
+
     }
 
     private List<Map<String, Integer>> getStatusCount(List<WatchContinuousSpo2Data> list) {

+ 222 - 57
fs-service/src/main/java/com/fs/watch/service/impl/WatchSportDataServiceImpl.java

@@ -2,7 +2,11 @@ package com.fs.watch.service.impl;
 
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.StringUtils;
+import com.fs.his.mapper.FsHealthPulseMapper;
+import com.fs.his.mapper.FsHealthSurfaceMapper;
 import com.fs.his.mapper.FsHealthTongueMapper;
+import com.fs.his.mapper.FsThirdDeviceDataMapper;
+import com.fs.watch.calculation.SleepScoreCalculator;
 import com.fs.watch.domain.WatchFsUser;
 import com.fs.watch.domain.WatchSportData;
 import com.fs.watch.domain.vo.*;
@@ -47,15 +51,18 @@ public class WatchSportDataServiceImpl implements WatchSportDataService {
     private WatchSleepDataService sleepDataService;
     @Autowired
     private FsHealthTongueMapper fsHealthTongueMapper;
+    @Autowired
+    private FsHealthSurfaceMapper fsHealthSurfaceMapper;
+    @Autowired
+    private FsHealthPulseMapper fsHealthPulseMapper;
+    @Autowired
+    private FsThirdDeviceDataMapper fsThirdDeviceDataMapper;
+    @Autowired
+    private SleepScoreCalculator sleepScoreCalculator;
 
 
     @Override
     public Boolean insert(WatchSportData sportData) {
-        //判断创建时间是否唯一
-        Integer num = mapper.queryByCreateTime(sportData.getCreateTime());
-        if (num != null && num > 0) {
-            return false;
-        }
         try {
             mapper.insert(sportData);
         } catch (Exception e) {
@@ -262,26 +269,95 @@ public class WatchSportDataServiceImpl implements WatchSportDataService {
     }
 
     @Override
-    public List<WatchSportRecordVo> queryRecord(String deviceId) {
+    public List<WatchSportRecordVo> queryRecord(String deviceId,Integer deviceType) {
+        String s = DateUtils.dateTimeNow("yyyy-MM-dd");
+        Date startTime = DateUtils.parseDate(s + " 00:00:00");
+        Date endTime = DateUtils.parseDate(s + " 23:59:59");
         if (StringUtils.isNotBlank(deviceId)) {
-            String s = DateUtils.dateTimeNow("yyyy-MM-dd");
-            Date startTime = DateUtils.parseDate(s + " 00:00:00");
-            Date endTime = DateUtils.parseDate(s + " 23:59:59");
-            List<WatchSportRecordVo> res = mapper.queryRecord(startTime, endTime, deviceId, null);
-            List<String> types = new ArrayList<>(Arrays.asList("游泳", "登山", "骑行", "跑步", "球类", "健走", "走路"));
-//            //其他运动
-            WatchSportRecordVo vo = mapper.getOtherData(null, null, deviceId, types);
+            WatchSportRecordVo vo =  new WatchSportRecordVo();
+            List<WatchSportRecordVo> res = new ArrayList<>();
+            if (deviceType == null || deviceType == 0) {
+                res = mapper.queryRecord(startTime, endTime, deviceId, null);
+                List<String> types = new ArrayList<>(Arrays.asList("游泳", "登山", "骑行", "跑步", "球类", "健走", "走路"));
+            //其他运动
+                vo = mapper.getOtherData(null, null, deviceId, types);
+                //计算时长
+//            mapper.getByTypeAndDeviceIdAndDate(deviceId,typ)
+            } else {
+                vo = fsThirdDeviceDataMapper.getOtherDataOther(startTime, endTime, deviceId, 6);
+                List<WatchSportRecordVo> list = fsThirdDeviceDataMapper.queryActivityRecord(startTime, endTime, deviceId, 6, null);
+                if (list != null && !list.isEmpty()) {
+                    for (WatchSportRecordVo data : list) {
+                        String sportType = data.getType();
+                        if (StringUtils.isNotBlank(sportType)) {
+                            data.setType(getActivityType(Integer.parseInt(sportType)));
+                            res.add(data);
+                        }
+                    }
+                }
+
+            }
             vo.setType("其他运动");
             res.add(vo);
-            //计算时长
-//            mapper.getByTypeAndDeviceIdAndDate(deviceId,typ)
             return res;
         }
         return null;
     }
 
+    private String getActivityType(Integer sportType) {
+        if (sportType == null) {
+            return null;
+        }
+        switch (sportType) {
+            case 1:
+                return "骑行";
+            case 5:
+                return "健步走";
+            case 9:
+                return "跑步";
+            case 13:
+                return "走路";
+            case 17:
+                return "登山";
+            case 21:
+                return "球类";
+            case 25:
+                return "游泳";
+            case 29:
+                return "羽毛球";
+            case 33:
+                return "足球";
+            case 37:
+                return "椭圆机";
+            case 41:
+                return "瑜伽";
+            case 45:
+                return "乒乓球";
+            case 49:
+                return "跳绳";
+            case 53:
+                return "划船机";
+            case 65:
+                return "自由训练";
+            case 69:
+                return "网球";
+            case 85:
+                return "自由运动";
+            case 89:
+                return "力量训练";
+            case 105:
+                return "舞蹈";
+            case 109:
+                return "呼啦圈";
+            case 113:
+                return "高尔夫";
+            default:
+                return null;
+        }
+    }
+
     @Override
-    public WatchSportIndexVo sportData(String userId, String deviceId,Boolean isFamily) {
+    public WatchSportIndexVo sportData(String userId, String deviceId,Boolean isFamily,Integer deviceType) {
         WatchSportIndexVo vo = new WatchSportIndexVo();
         if (isFamily != null && isFamily) {
             WatchFamilyUserVo watchFamilyUserVo = familyUserService.selectWatchFamilyUserByDeviceId(deviceId, null);
@@ -304,18 +380,56 @@ public class WatchSportDataServiceImpl implements WatchSportDataService {
 
         //2.查询当日完成
         //2.1卡路里,步数
-        WatchSportData map = mapper.sumStepAndCalorie(deviceId);
-        if (map != null) {
-            vo.setStep(map.getStep().toString());
-            vo.setCalorie(String.format("%.2f", map.getCalorie()));
+        if (deviceType == null || deviceType == 0) {
+            WatchSportData map = mapper.sumStepAndCalorie(deviceId);
+            if (map != null) {
+                vo.setStep(map.getStep().toString());
+                vo.setCalorie(String.format("%.2f", map.getCalorie()));
+            }
+            //2.2 时长
+            Long sportTime = getSportTime(deviceId, null, "today");
+            //2.2.1 活动
+            Long activityTime = getActivityTime(deviceId);//分钟
+            //2.2.2 锻炼
+            vo.setSport(sportTime == null ? "0" : sportTime.toString());
+            vo.setActivity(activityTime == null ? "0" : new BigDecimal(activityTime).divide(new BigDecimal(60), 2, RoundingMode.HALF_UP) + "");
+        } else {
+            Date starTime = DateUtils.truncate(new Date(), Calendar.DATE);
+            Date endTime = DateUtils.getNowDate();
+            //步数
+            WatchSportRecordVo map1 = fsThirdDeviceDataMapper.getOtherData(starTime,endTime,deviceId,5,null);
+            //运动
+            WatchSportRecordVo map2 = fsThirdDeviceDataMapper.getOtherData(starTime,endTime,deviceId,6,null);
+            long stepTotal = 0L;
+            float calorieTotal = 0f;
+            vo.setActivity("0");
+            vo.setSport("0");
+            if (map1 != null) {
+                stepTotal = stepTotal + (map1.getStep()==null?0:map1.getStep());
+                if (map1.getCalorie()!=null && map1.getCalorie()>0) {
+                    calorieTotal = map1.getCalorie();
+                }
+                Float time = map1.getTime();
+                if (time != null) {
+                    vo.setActivity(String.valueOf(time));
+                }
+
+            }
+            if (map2 != null) {
+                stepTotal = stepTotal + (map2.getStep()==null?0:map2.getStep());
+                Float time = map2.getTime();
+                if (time != null) {
+                    vo.setSport(String.valueOf(time*60));
+                }
+
+            }
+            //2.2.2 锻炼
+            vo.setStep(String.valueOf(stepTotal));
+            vo.setCalorie(String.valueOf(calorieTotal));
+
         }
-        //2.2 时长
-        Long sportTime = getSportTime(deviceId, null, "today");
-        //2.2.1 活动
-        Long activityTime = getActivityTime(deviceId);//分钟
-        //2.2.2 锻炼
-        vo.setSport(sportTime == null ? "0" : sportTime.toString());
-        vo.setActivity(activityTime == null ? "0" : new BigDecimal(activityTime).divide(new BigDecimal(60), 2, RoundingMode.HALF_UP) + "");
+
+
         return vo;
     }
 
@@ -498,32 +612,64 @@ public class WatchSportDataServiceImpl implements WatchSportDataService {
     }
 
     @Override
-    public AppFsUserHealthVo getUserHealthInfoByDeviceId(String deviceId,Date startTime, Date endTime,Long userId) {
+    public AppFsUserHealthVo getUserHealthInfoByDeviceId(String deviceId,Date startTime, Date endTime,Long userId,Integer deviceType) {
         AppFsUserHealthVo vo = new AppFsUserHealthVo();
         // 格式化时间
-        String startDate = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime);
-        String endDate = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime);
-        // 异步任务 1:睡眠状态
-        CompletableFuture<String> sleepFuture = CompletableFuture.supplyAsync(() ->
-                sleepDataService.getSleepStatus(startTime, endTime, deviceId)
-        );
-
-
-        // 异步任务 2:运动数据
-        CompletableFuture<Void> sportFuture = CompletableFuture.runAsync(() -> {
-            List<WatchSportData> list = mapper.getByType(startDate, endDate, deviceId, null);
-            int step = 0;
-            float calorie = 0;
-            if (list != null && !list.isEmpty()) {
-                for (WatchSportData data : list) {
-                    step += data.getStep() == null ? 0 : data.getStep();
-                    calorie += data.getCalorie() == null ? 0 : data.getCalorie();
-                }
+        String startDate = DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", startTime);
+        String endDate = DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", endTime);
+        CompletableFuture<String>  sleepFuture = null;
+        CompletableFuture<Void>  sportFuture = null;
+        if (StringUtils.isNotBlank(deviceId)){
+            // 异步任务 1:睡眠状态
+            if (deviceType == null || deviceType == 0){
+                sleepFuture = CompletableFuture.supplyAsync(() ->
+                        sleepDataService.getSleepStatus(startTime, endTime, deviceId)
+                );
+
+
+                // 异步任务 2:运动数据
+                sportFuture = CompletableFuture.runAsync(() -> {
+                    List<WatchSportData> list = mapper.getByType(startDate, endDate, deviceId, null);
+                    int step = 0;
+                    float calorie = 0;
+                    if (list != null && !list.isEmpty()) {
+                        for (WatchSportData data : list) {
+                            step += data.getStep() == null ? 0 : data.getStep();
+                            calorie += data.getCalorie() == null ? 0 : data.getCalorie();
+                        }
+                    }
+                    vo.setStep(step);
+                    vo.setCalorie((int) calorie);
+                });
+            } else {
+                sleepFuture = CompletableFuture.supplyAsync(() ->
+                        sleepScoreCalculator.getSleepStatus(startTime, endTime, deviceId)
+                );
+
+
+                // 异步任务 2:运动数据
+                sportFuture = CompletableFuture.runAsync(() -> {
+//                    List<WatchSportData> list = mapper.getByType(startDate, endDate, deviceId, null);
+                    WatchSportRecordVo otherData1 = fsThirdDeviceDataMapper.getOtherData(startTime, endTime, deviceId, 5, null);
+                    WatchSportRecordVo otherData2 = fsThirdDeviceDataMapper.getOtherData(startTime, endTime, deviceId, 6, null);
+                    int step = 0;
+                    float calorie = 0;
+                    if (otherData1 != null) {
+                        step += otherData1.getStep() == null ? 0 : Integer.parseInt(otherData1.getStep().toString());
+                        calorie += otherData1.getCalorie() == null ? 0 : otherData1.getCalorie();
+                    }
+                    if (otherData2 != null) {
+                        step += otherData2.getStep() == null ? 0 : Integer.parseInt(otherData2.getStep().toString());
+                        calorie += otherData2.getCalorie() == null ? 0 : otherData2.getCalorie();
+                    }
+                    vo.setStep(step);
+                    vo.setCalorie((int) calorie);
+                });
             }
-            vo.setStep(step);
-            vo.setCalorie((int) calorie);
-        });
 
+
+
+        }
         // 异步任务 3:舌诊数据
         CompletableFuture<Void> tongueFuture = CompletableFuture.runAsync(() -> {
             if (userId != null){
@@ -531,14 +677,33 @@ public class WatchSportDataServiceImpl implements WatchSportDataService {
                 vo.setTongueDateList(list);
             }
         });
-
-        // 等待所有任务完成
-        CompletableFuture.allOf(sleepFuture, sportFuture,tongueFuture).join();
-        try {
-            vo.setSleepStatus(sleepFuture.get());
-        } catch (Exception e) {
-            log.error("获取睡眠状态失败: {}", e.getMessage(), e);
-            vo.setSleepStatus("未知");
+        // 异步任务 3:面诊数据
+        CompletableFuture<Void> surfaceFuture = CompletableFuture.runAsync(() -> {
+            if (userId != null){
+                List<String> list = fsHealthSurfaceMapper.selectListByDateAndUserId(startDate, endDate, userId);
+                vo.setSurfaceDateList(list);
+            }
+        });
+        // 异步任务 3:脉诊数据
+        CompletableFuture<Void> pulseFuture = CompletableFuture.runAsync(() -> {
+            if (userId != null){
+                List<String> list = fsHealthPulseMapper.selectListByDateAndUserId(startDate, endDate, userId);
+                vo.setPulseDateList(list);
+            }
+        });
+        if(StringUtils.isNotBlank(deviceId)){
+            // 等待所有任务完成
+            CompletableFuture.allOf(sleepFuture, sportFuture,tongueFuture,surfaceFuture,pulseFuture).join();
+
+            try {
+                vo.setSleepStatus(sleepFuture.get());
+            } catch (Exception e) {
+                log.error("获取睡眠状态失败: {}", e.getMessage(), e);
+                vo.setSleepStatus("未知");
+            }
+        } else {
+            // 等待所有任务完成
+            CompletableFuture.allOf(tongueFuture,surfaceFuture,pulseFuture).join();
         }
         return vo;
     }

+ 0 - 5
fs-service/src/main/java/com/fs/watch/service/impl/WatchTemperatureDataServiceImpl.java

@@ -31,11 +31,6 @@ public class WatchTemperatureDataServiceImpl implements WatchTemperatureDataServ
 
     @Override
     public Boolean insert(WatchTemperatureData watchTemperatureData) {
-        //判断创建时间是否唯一
-        Integer num = mapper.queryByCreateTime(watchTemperatureData.getCreateTime());
-        if (num != null && num > 0) {
-            return false;
-        }
         try {
             mapper.insert(watchTemperatureData);
         } catch (Exception e) {

+ 0 - 4
fs-service/src/main/java/com/fs/watch/service/impl/WatchThirdBkDataServiceImpl.java

@@ -41,10 +41,6 @@ implements WatchThirdBkDataService {
 
     @Override
     public Boolean insert(WatchThirdBkData watchThirdBkData) {
-        Integer num = mapper.queryByCreateTime(watchThirdBkData.getCreateTime());
-        if (num != null && num > 0) {
-            return false;
-        }
         try {
             mapper.insert(watchThirdBkData);
         } catch (Exception e) {

+ 76 - 22
fs-service/src/main/java/com/fs/watch/service/impl/WatchThirdBpDataServiceImpl.java

@@ -1,7 +1,10 @@
 package com.fs.watch.service.impl;
 
+import com.alibaba.fastjson.JSONObject;
 import com.fs.common.utils.DateUtils;
 import com.fs.common.utils.StringUtils;
+import com.fs.his.domain.FsThirdDeviceData;
+import com.fs.his.mapper.FsThirdDeviceDataMapper;
 import com.fs.watch.domain.WatchThirdBpData;
 import com.fs.watch.mapper.WatchThirdBpDataMapper;
 import com.fs.watch.service.WatchThirdBpDataService;
@@ -9,10 +12,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 /**
 * @author Administrator
@@ -24,6 +24,8 @@ import java.util.Map;
 public class WatchThirdBpDataServiceImpl implements WatchThirdBpDataService {
     @Autowired
     private WatchThirdBpDataMapper mapper;
+    @Autowired
+    private FsThirdDeviceDataMapper fsThirdDeviceDataMapper;
 
     /**
      * 新增数据
@@ -33,11 +35,6 @@ public class WatchThirdBpDataServiceImpl implements WatchThirdBpDataService {
      */
     @Override
     public Boolean insert(WatchThirdBpData watchThirdBpData) {
-        //判断创建时间是否唯一
-        Integer num = mapper.queryByCreateTime(watchThirdBpData.getCreateTime());
-        if (num != null && num > 0) {
-            return false;
-        }
         try {
             mapper.insert(watchThirdBpData);
         } catch (Exception e) {
@@ -69,8 +66,32 @@ public class WatchThirdBpDataServiceImpl implements WatchThirdBpDataService {
     }
 
     @Override
-    public List<WatchThirdBpData> queryBpByDate(String startTime, String endTime, String deviceId, Integer status) {
-        return mapper.queryBpByDate(startTime,endTime,deviceId,status);
+    public List<WatchThirdBpData> queryBpByDate(String startTime, String endTime, String deviceId, Integer status,Integer deviceType) {
+        if (deviceType == null || deviceType == 0) {
+            return mapper.queryBpByDate(startTime,endTime,deviceId,status);
+        } else {
+            List<WatchThirdBpData> voList = new ArrayList<>();
+            List<FsThirdDeviceData> list = fsThirdDeviceDataMapper.selectListByDateAndDeviceIdAndRecordType(DateUtils.dateTime("yyyy-MM-dd HH:mm:ss",startTime), DateUtils.dateTime("yyyy-MM-dd HH:mm:ss",endTime), deviceId, 0, status);
+
+            if (list != null && !list.isEmpty()) {
+                for (FsThirdDeviceData fsThirdDeviceData : list) {
+                    WatchThirdBpData watchThirdBpData = new WatchThirdBpData();
+                    watchThirdBpData.setDeviceId(fsThirdDeviceData.getDeviceId());
+                    String recordValue = fsThirdDeviceData.getRecordValue();
+                    if (StringUtils.isNotBlank(recordValue)) {
+                        JSONObject jsonObject = JSONObject.parseObject(recordValue);
+                        watchThirdBpData.setSbp(Integer.valueOf(jsonObject.get("sdb").toString()));
+                        watchThirdBpData.setDbp(Integer.valueOf(jsonObject.get("dbp").toString()));
+                        watchThirdBpData.setCreateTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",fsThirdDeviceData.getCreateTime()));
+                        watchThirdBpData.setStatus(fsThirdDeviceData.getStatus());
+                        voList.add(watchThirdBpData);
+                    }
+
+                }
+            }
+            return voList;
+        }
+
     }
 
 
@@ -115,31 +136,64 @@ public class WatchThirdBpDataServiceImpl implements WatchThirdBpDataService {
     }
 
     @Override
-    public List<Map<String, Object>> countBpByDate(Date startTime, Date endTime, String deviceId) {
+    public List<Map<String, Object>> countBpByDate(Date startTime, Date endTime, String deviceId,Integer deviceType) {
         if (StringUtils.isBlank(deviceId)) {
             return null;
         }
         //返回对象
         List<Map<String, Object>>  res = null;
-        res = mapper.countBpByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
-                DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),deviceId);
+        if (deviceType == null || deviceType == 0) {
+            res = mapper.countBpByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
+                    DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),deviceId);
+        } else {
+            res = fsThirdDeviceDataMapper.countByDateAndDeviceIdAndRecordType(startTime,endTime,deviceId,0,null);
+        }
+
 
         return res;
     }
 
     @Override
-    public int countBpPageByDate(Date startTime, Date endTime, String deviceId, Integer status) {
-        return mapper.countBpPageByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
-                DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),
-                deviceId,status);
+    public int countBpPageByDate(Date startTime, Date endTime, String deviceId, Integer status,Integer deviceType) {
+        if (deviceType == null || deviceType == 0) {
+            return mapper.countBpPageByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
+                    DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),
+                    deviceId,status);
+        } else {
+            return fsThirdDeviceDataMapper.countPageByDateAndDeviceIdAndRecordType(startTime,endTime,deviceId,0,status);
+        }
+
     }
 
     @Override
-    public List<WatchThirdBpData> queryBgPageByDate(Date startTime, Date endTime, String deviceId, Integer status, Integer num, Integer size) {
+    public List<WatchThirdBpData> queryBgPageByDate(Date startTime, Date endTime, String deviceId, Integer status, Integer num, Integer size,Integer deviceType) {
         if (StringUtils.isNotBlank(deviceId)) {
-            return mapper.queryBgPageByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
-                    DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),
-                    deviceId,status,num,size);
+            if (deviceType == null || deviceType == 0) {
+                return mapper.queryBgPageByDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime),
+                        DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime),
+                        deviceId,status,num,size);
+            } else {
+                List<WatchThirdBpData> voList = new ArrayList<>();
+                List<FsThirdDeviceData> list = fsThirdDeviceDataMapper.queryPageByDateAndDeviceIdAndRecordType(startTime, endTime, deviceId, 0, status, num, size);
+                if (list != null && !list.isEmpty()) {
+                    for (FsThirdDeviceData fsThirdDeviceData : list) {
+                        WatchThirdBpData vo = new WatchThirdBpData();
+                        vo.setDeviceId(fsThirdDeviceData.getDeviceId());
+                        String recordValue = fsThirdDeviceData.getRecordValue();
+                        if (StringUtils.isNotBlank(recordValue)) {
+                            JSONObject jsonObject = JSONObject.parseObject(recordValue);
+                            vo.setDbp(Integer.valueOf(jsonObject.get("dbp").toString()));
+                            vo.setSbp(Integer.valueOf(jsonObject.get("sdb").toString()));
+                            vo.setStatus(fsThirdDeviceData.getStatus());
+                            vo.setCreateTime(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",fsThirdDeviceData.getCreateTime()));
+
+                        }
+                        voList.add(vo);
+                    }
+                }
+                return voList;
+            }
+
         } else {
             return null;
         }

Некоторые файлы не были показаны из-за большого количества измененных файлов