Просмотр исходного кода

Merge remote-tracking branch 'origin/master'

yjwang 1 месяц назад
Родитель
Сommit
8af743fd54
100 измененных файлов с 3454 добавлено и 608 удалено
  1. 7 0
      fs-service/src/main/java/com/fs/aiChat/mapper/InterestAiChatSessionMapper.java
  2. 78 0
      fs-service/src/main/java/com/fs/his/domain/FsHealthPulse.java
  3. 83 0
      fs-service/src/main/java/com/fs/his/domain/FsHealthSurface.java
  4. 84 0
      fs-service/src/main/java/com/fs/his/domain/FsUserAdditionalData.java
  5. 74 0
      fs-service/src/main/java/com/fs/his/mapper/FsHealthPulseMapper.java
  6. 77 0
      fs-service/src/main/java/com/fs/his/mapper/FsHealthSurfaceMapper.java
  7. 68 0
      fs-service/src/main/java/com/fs/his/mapper/FsUserAdditionalDataMapper.java
  8. 16 0
      fs-service/src/main/java/com/fs/his/param/FsHealthPulseListUParam.java
  9. 16 0
      fs-service/src/main/java/com/fs/his/param/FsHealthSurfaceListUParam.java
  10. 2 0
      fs-service/src/main/java/com/fs/his/param/FsHealthTongueListUParam.java
  11. 65 0
      fs-service/src/main/java/com/fs/his/service/IFsUserAdditionalDataService.java
  12. 98 0
      fs-service/src/main/java/com/fs/his/service/impl/FsUserAdditionalDataServiceImpl.java
  13. 69 0
      fs-service/src/main/java/com/fs/his/vo/FsHealthPulseListVO.java
  14. 83 0
      fs-service/src/main/java/com/fs/his/vo/FsHealthSurfaceListVO.java
  15. 0 83
      fs-service/src/main/java/com/fs/watch/domain/FsMonitorDataType.java
  16. 96 0
      fs-service/src/main/java/com/fs/watch/domain/WatchAudioMsgLog.java
  17. 0 108
      fs-service/src/main/java/com/fs/watch/domain/WatchDeviceBeginnerGuide.java
  18. 56 0
      fs-service/src/main/java/com/fs/watch/domain/WatchDeviceWeek.java
  19. 89 0
      fs-service/src/main/java/com/fs/watch/domain/WatchSosCallLogs.java
  20. 4 0
      fs-service/src/main/java/com/fs/watch/domain/vo/AppFsUserHealthReportVo.java
  21. 4 0
      fs-service/src/main/java/com/fs/watch/domain/vo/AppFsUserHealthVo.java
  22. 4 0
      fs-service/src/main/java/com/fs/watch/domain/vo/AppFsUserVo.java
  23. 4 0
      fs-service/src/main/java/com/fs/watch/domain/vo/AppWatchSleepDataVo.java
  24. 69 0
      fs-service/src/main/java/com/fs/watch/domain/vo/WatchDeviceInfoAndIotExportVO.java
  25. 0 9
      fs-service/src/main/java/com/fs/watch/domain/vo/WatchDeviceInfoAndUserIdVo.java
  26. 2 0
      fs-service/src/main/java/com/fs/watch/domain/vo/WatchSleepDataVo.java
  27. 2 0
      fs-service/src/main/java/com/fs/watch/mapper/WatchAlarmDataMapper.java
  28. 12 0
      fs-service/src/main/java/com/fs/watch/mapper/WatchAudioMsgLogMapper.java
  29. 4 8
      fs-service/src/main/java/com/fs/watch/mapper/WatchBloodPressureDataMapper.java
  30. 2 0
      fs-service/src/main/java/com/fs/watch/mapper/WatchDeviceInfoClicMapper.java
  31. 4 0
      fs-service/src/main/java/com/fs/watch/mapper/WatchDeviceInfoMapper.java
  32. 68 0
      fs-service/src/main/java/com/fs/watch/mapper/WatchDeviceWeekMapper.java
  33. 2 0
      fs-service/src/main/java/com/fs/watch/mapper/WatchDoctorMapper.java
  34. 2 0
      fs-service/src/main/java/com/fs/watch/mapper/WatchHeartRateDataMapper.java
  35. 36 0
      fs-service/src/main/java/com/fs/watch/mapper/WatchSosCallLogsMapper.java
  36. 2 0
      fs-service/src/main/java/com/fs/watch/mapper/WatchSpo2DataMapper.java
  37. 15 0
      fs-service/src/main/java/com/fs/watch/param/DeviceSendParam.java
  38. 0 1
      fs-service/src/main/java/com/fs/watch/param/WatchChartQueryParam.java
  39. 15 0
      fs-service/src/main/java/com/fs/watch/param/WatchDeviceInfoQueryParam.java
  40. 8 0
      fs-service/src/main/java/com/fs/watch/service/DeviceSetUpService.java
  41. 7 0
      fs-service/src/main/java/com/fs/watch/service/WatchAudioMsgLogService.java
  42. 1 1
      fs-service/src/main/java/com/fs/watch/service/WatchBasicInfoService.java
  43. 0 24
      fs-service/src/main/java/com/fs/watch/service/WatchDeviceBeginnerGuideService.java
  44. 3 0
      fs-service/src/main/java/com/fs/watch/service/WatchDeviceInfoClicService.java
  45. 2 0
      fs-service/src/main/java/com/fs/watch/service/WatchDeviceInfoService.java
  46. 11 0
      fs-service/src/main/java/com/fs/watch/service/WatchDeviceWeekService.java
  47. 33 0
      fs-service/src/main/java/com/fs/watch/service/WatchSosCallLogsService.java
  48. 63 0
      fs-service/src/main/java/com/fs/watch/service/impl/DeviceSetUpServiceImpl.java
  49. 38 1
      fs-service/src/main/java/com/fs/watch/service/impl/WatchAlarmDataServiceImpl.java
  50. 80 0
      fs-service/src/main/java/com/fs/watch/service/impl/WatchAudioMsgLogServiceImpl.java
  51. 552 31
      fs-service/src/main/java/com/fs/watch/service/impl/WatchBasicInfoServiceImpl.java
  52. 0 5
      fs-service/src/main/java/com/fs/watch/service/impl/WatchBloodGlucoseDataServiceImpl.java
  53. 0 5
      fs-service/src/main/java/com/fs/watch/service/impl/WatchBloodPressureDataServiceImpl.java
  54. 0 4
      fs-service/src/main/java/com/fs/watch/service/impl/WatchContinuousSpo2DataServiceImpl.java
  55. 3 3
      fs-service/src/main/java/com/fs/watch/service/impl/WatchDataServiceImpl.java
  56. 0 79
      fs-service/src/main/java/com/fs/watch/service/impl/WatchDeviceBeginnerGuideServiceImpl.java
  57. 0 4
      fs-service/src/main/java/com/fs/watch/service/impl/WatchDeviceDataServiceImpl.java
  58. 97 0
      fs-service/src/main/java/com/fs/watch/service/impl/WatchDeviceInfoClicServiceImpl.java
  59. 12 4
      fs-service/src/main/java/com/fs/watch/service/impl/WatchDeviceInfoServiceImpl.java
  60. 0 4
      fs-service/src/main/java/com/fs/watch/service/impl/WatchDeviceStatusServiceImpl.java
  61. 20 0
      fs-service/src/main/java/com/fs/watch/service/impl/WatchDeviceWeekServiceImpl.java
  62. 0 4
      fs-service/src/main/java/com/fs/watch/service/impl/WatchEcgDataServiceImpl.java
  63. 0 5
      fs-service/src/main/java/com/fs/watch/service/impl/WatchFatigueDataServiceImpl.java
  64. 0 6
      fs-service/src/main/java/com/fs/watch/service/impl/WatchHeartRateDataServiceImpl.java
  65. 0 5
      fs-service/src/main/java/com/fs/watch/service/impl/WatchMultiLeadsEcgDataServiceImpl.java
  66. 0 5
      fs-service/src/main/java/com/fs/watch/service/impl/WatchPpgDataServiceImpl.java
  67. 15 15
      fs-service/src/main/java/com/fs/watch/service/impl/WatchRriDataServiceImpl.java
  68. 84 41
      fs-service/src/main/java/com/fs/watch/service/impl/WatchSleepDataServiceImpl.java
  69. 72 0
      fs-service/src/main/java/com/fs/watch/service/impl/WatchSosCallLogsServiceImpl.java
  70. 0 5
      fs-service/src/main/java/com/fs/watch/service/impl/WatchSpo2DataServiceImpl.java
  71. 56 32
      fs-service/src/main/java/com/fs/watch/service/impl/WatchSportDataServiceImpl.java
  72. 0 5
      fs-service/src/main/java/com/fs/watch/service/impl/WatchTemperatureDataServiceImpl.java
  73. 0 4
      fs-service/src/main/java/com/fs/watch/service/impl/WatchThirdBkDataServiceImpl.java
  74. 0 5
      fs-service/src/main/java/com/fs/watch/service/impl/WatchThirdBpDataServiceImpl.java
  75. 0 4
      fs-service/src/main/java/com/fs/watch/service/impl/WatchThirdUaDataServiceImpl.java
  76. 25 18
      fs-service/src/main/java/com/fs/watch/service/impl/WatchUserServiceImpl.java
  77. 23 0
      fs-service/src/main/java/com/fs/watch/task/HealthCheckTask.java
  78. 207 0
      fs-service/src/main/java/com/fs/watch/utils/AudioConvertUtil.java
  79. 53 0
      fs-service/src/main/java/com/fs/watch/utils/MD5Utils.java
  80. 42 12
      fs-service/src/main/java/com/fs/watch/utils/MyHttpUtils.java
  81. 11 0
      fs-service/src/main/resources/application-config-druid-jnmy.yml
  82. 136 0
      fs-service/src/main/resources/mapper/his/FsHealthPulseMapper.xml
  83. 148 0
      fs-service/src/main/resources/mapper/his/FsHealthSurfaceMapper.xml
  84. 124 0
      fs-service/src/main/resources/mapper/his/FsUserAdditionalDataMapper.xml
  85. 0 15
      fs-service/src/main/resources/mapper/his/FsUserMapper.xml
  86. 11 0
      fs-service/src/main/resources/mapper/his/InterestAiChatSessionMapper.xml
  87. 9 0
      fs-service/src/main/resources/mapper/watch/WatchDeviceInfoClicMapper.xml
  88. 18 11
      fs-watch/src/main/java/com/fs/app/controller/WatchController.java
  89. 20 12
      fs-watch/src/main/java/com/fs/app/controller/WatchUserController.java
  90. 5 4
      fs-watch/src/main/java/com/fs/app/utils/JwtUtils.java
  91. 15 7
      fs-watch/src/main/java/com/fs/framework/config/DataSourceConfig.java
  92. 3 2
      fs-watch/src/main/java/com/fs/framework/config/MyBatisConfig.java
  93. 5 14
      fs-watch/src/main/java/com/fs/framework/config/RedisConfig.java
  94. 3 0
      fs-watch/src/main/java/com/fs/watch/controller/DeviceSetUpController.java
  95. 33 0
      fs-watch/src/main/java/com/fs/watch/controller/WatchAudioDataController.java
  96. 57 0
      fs-watch/src/main/java/com/fs/watch/controller/WatchCommonController.java
  97. 16 0
      fs-watch/src/main/java/com/fs/watch/controller/WatchDeviceInfoClicController.java
  98. 16 2
      fs-watch/src/main/java/com/fs/watch/controller/WatchDeviceInfoController.java
  99. 4 0
      fs-watch/src/main/java/com/fs/watch/controller/WatchFatigueDataController.java
  100. 1 1
      fs-watch/src/main/java/com/fs/watch/controller/WatchGetDataController.java

+ 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);
 }

+ 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;
+}

+ 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);
+
+
+
+}

+ 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;
 }

+ 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);
+
+}

+ 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;
+}

+ 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();
-    }
-}

+ 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;
+
+
+
+}

+ 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;
+    }
+
+}
+

+ 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;
 
 }

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

@@ -119,4 +119,8 @@ public class AppFsUserVo {
     /** 微信公众号OPENID */
     @Excel(name = "微信公众号OPENID")
     private String mpOpenId;
+    /** 既往病史 */
+    @Excel(name = "既往病史")
+    private String previousMedicalHistory;
+
 }

+ 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;
 }

+ 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; //时间
+
     /**
      * 开始时间
      */

+ 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;
+
 }

+ 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);
+}

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

@@ -46,5 +46,5 @@ 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);
 }

+ 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 {
+
+}

+ 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);
+
+
+}

+ 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;
+    }
+}

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

@@ -1,14 +1,27 @@
 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.mapper.FsHealthPulseMapper;
+import com.fs.his.mapper.FsHealthSurfaceMapper;
+import com.fs.his.mapper.FsHealthTongueMapper;
+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.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 +29,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 +72,24 @@ 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;
+    private static final ObjectMapper objectMapper = new ObjectMapper();
+
 
     /**
      * 新增数据
@@ -64,11 +99,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 +226,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 +238,131 @@ 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) {
         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);
+        });
+        CompletableFuture<Void> totalScoreFuture = null;
+        if (StringUtils.isNotBlank(deviceId)) {
+            //获取异常数据及分析
+            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 +386,414 @@ 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;
+
+    private void getAiSuggestion(Date startTime, Date endTime, String deviceId, Long watchUserId, Boolean isFamily, AppFsUserHealthReportVo res) {
+        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);
+            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);
+                //3.血压
+                calculateBp(deviceId, start, end, bpStr, dateToStr);
+
+
+                //4.血糖
+                calculateBg(deviceId, start, end, bgStr, dateToStr);
+                //5.心率
+                calculateHr(deviceId, start, end, hrStr, dateToStr);
+                //6.血氧
+                calculateSpo2(deviceId, start, end, spo2Str, dateToStr);
+
+                //7.睡眠
+                calculateSleep(deviceId, DateUtils.parseDateToStr("yyyy-MM-dd", currentStartDate), sleepStr, dateToStr);
+            }
+            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) {
+        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(" 分钟,");
+            }
+        }
+    }
+
+
+    /**
+     * 计算每天血氧
+     *
+     * @param deviceId
+     * @param currentStartDate
+     * @param currentEndDate
+     * @param spo2Str
+     * @param dateToStr
+     */
+    private void calculateSpo2(String deviceId, String currentStartDate, String currentEndDate, StringBuilder spo2Str, String dateToStr) {
+        Float value = watchSpo2DataMapper.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) {
+        Map<String, Integer> map = watchHeartRateDataMapper.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) {
+        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 ");
+        }
+    }
+
+    /**
+     * 计算每天血压
+     *
+     * @param deviceId
+     * @param currentStartDate
+     * @param currentEndDate
+     * @param bpStr
+     */
+    private void calculateBp(String deviceId, String currentStartDate, String currentEndDate, StringBuilder bpStr, String dateToStr) {
+        Map<String, Integer> map = watchBloodPressureDataMapper.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) {
+        List<WatchSportData> list = sportDataMapper.getByType(currentStartDate, currentEndDate, deviceId, null);
+        int dailyStep = 0;
+        if (list != null && !list.isEmpty()) {
+            for (WatchSportData data : list) {
+                dailyStep += data.getStep() == null ? 0 : data.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 +802,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 +814,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 +831,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;
     }
 

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

@@ -34,11 +34,6 @@ public class WatchBloodGlucoseDataServiceImpl implements WatchBloodGlucoseDataSe
 
     @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) {

+ 0 - 5
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) {

+ 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) {

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

@@ -264,7 +264,7 @@ public class WatchDataServiceImpl implements WatchDataService {
                 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));
                     }
                 }
             }
@@ -668,8 +668,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;
+    }
+
 }

+ 12 - 4
fs-service/src/main/java/com/fs/watch/service/impl/WatchDeviceInfoServiceImpl.java

@@ -9,8 +9,8 @@ import com.fs.company.service.ICompanyService;
 import com.fs.company.service.ICompanyUserService;
 import com.fs.his.service.IFsDoctorService;
 import com.fs.his.service.IFsUserService;
-import com.fs.watch.domain.*;
 import com.fs.watch.domain.vo.FsUserAndCompanyAndDoctorVo;
+import com.fs.watch.domain.*;
 import com.fs.watch.domain.vo.WatchDeviceInfoVo;
 import com.fs.watch.mapper.*;
 import com.fs.watch.param.WatchDeviceInfoQueryParam;
@@ -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.selectCompanyUserNameUserById(Long.valueOf(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) {

+ 0 - 6
fs-service/src/main/java/com/fs/watch/service/impl/WatchHeartRateDataServiceImpl.java

@@ -30,12 +30,6 @@ public class WatchHeartRateDataServiceImpl implements WatchHeartRateDataService
 
     @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) {

+ 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);

+ 84 - 41
fs-service/src/main/java/com/fs/watch/service/impl/WatchSleepDataServiceImpl.java

@@ -17,6 +17,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 +27,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.*;
@@ -60,11 +62,6 @@ public class WatchSleepDataServiceImpl implements WatchSleepDataService {
 
     @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 +151,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 +221,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;
         }
     }
@@ -283,12 +307,15 @@ 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);
+//                log.info(currentDate);
             WatchSleepDataVo watchSleepDataVo = getSleepSection(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, currentDate), deviceId);
+
             if (watchSleepDataVo != null && watchSleepDataVo.getSleepSection() !=null && watchSleepDataVo.getSleepSection().size() > 0) {
+                watchSleepDataVo.setDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, currentDate));
+                watchSleepDataVos.add(watchSleepDataVo);
                 AppWatchSleepDataVo appWatchSleepDataVo = parserResult(deviceId, watchSleepDataVo);
                 //统计图对象
                 sleepSection.addAll(appWatchSleepDataVo.getSleepSection());
@@ -322,6 +349,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 +483,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 +494,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 +539,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 +556,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;
+    }
+
+}

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

@@ -38,11 +38,6 @@ public class WatchSpo2DataServiceImpl implements WatchSpo2DataService {
 
     @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) {

+ 56 - 32
fs-service/src/main/java/com/fs/watch/service/impl/WatchSportDataServiceImpl.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.mapper.FsHealthPulseMapper;
+import com.fs.his.mapper.FsHealthSurfaceMapper;
 import com.fs.his.mapper.FsHealthTongueMapper;
 import com.fs.watch.domain.WatchFsUser;
 import com.fs.watch.domain.WatchSportData;
@@ -47,15 +49,14 @@ public class WatchSportDataServiceImpl implements WatchSportDataService {
     private WatchSleepDataService sleepDataService;
     @Autowired
     private FsHealthTongueMapper fsHealthTongueMapper;
+    @Autowired
+    private FsHealthSurfaceMapper fsHealthSurfaceMapper;
+    @Autowired
+    private FsHealthPulseMapper fsHealthPulseMapper;
 
 
     @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) {
@@ -503,27 +504,32 @@ public class WatchSportDataServiceImpl implements WatchSportDataService {
         // 格式化时间
         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();
+        CompletableFuture<String>  sleepFuture = null;
+        CompletableFuture<Void>  sportFuture = null;
+        if (StringUtils.isNotBlank(deviceId)){
+            // 异步任务 1:睡眠状态
+            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);
-        });
+                vo.setStep(step);
+                vo.setCalorie((int) calorie);
+            });
+
 
+        }
         // 异步任务 3:舌诊数据
         CompletableFuture<Void> tongueFuture = CompletableFuture.runAsync(() -> {
             if (userId != null){
@@ -531,14 +537,32 @@ 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) {

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

@@ -33,11 +33,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) {

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

@@ -34,10 +34,6 @@ public class WatchThirdUaDataServiceImpl implements WatchThirdUaDataService {
 
     @Override
     public Boolean insert(WatchThirdUaData watchThirdUaData) {
-        Integer num = mapper.queryByCreateTime(watchThirdUaData.getCreateTime());
-        if (num != null && num > 0) {
-            return false;
-        }
         try {
             mapper.insert(watchThirdUaData);
         } catch (Exception e) {

+ 25 - 18
fs-service/src/main/java/com/fs/watch/service/impl/WatchUserServiceImpl.java

@@ -379,7 +379,7 @@ public class WatchUserServiceImpl implements WatchUserService {
         String phone = watchFsUser.getPhone();
         if (StringUtils.isNotBlank(phone)) {
             if (phone.length() > 13) {
-                watchFsUser.setPhone(PhoneUtil.decryptPhone(phone));
+                watchFsUser.setPhone(PhoneUtil.decryptPhoneMk(phone));
             }
         }
         return watchFsUser;
@@ -393,27 +393,34 @@ public class WatchUserServiceImpl implements WatchUserService {
     @Override
     public AppFsUserVo getUserInfoByDeviceId(String deviceId, Boolean isFamily, Long watchUserId) {
         AppFsUserVo appFsUserVo = new AppFsUserVo();
-        if (isFamily) {
-            WatchFamilyUserVo familyUser = watchFamilyUserService.selectWatchFamilyUserByDeviceId(deviceId, watchUserId);
-            if (familyUser != null) {
-                BeanUtils.copyProperties(familyUser, appFsUserVo);
-                if (familyUser.getBirthday() != null) {
-                    appFsUserVo.setAge(getAge(familyUser.getBirthday()));
-                }
-            }
+        if (StringUtils.isBlank(deviceId)) {
+            //查询原有用户信息
+            FsUser fsUser = fsUserService.selectFsUserByUserId(watchUserId);
+            BeanUtils.copyProperties(fsUser, appFsUserVo);
+            return appFsUserVo;
         } else {
-            //根据设备id获取用户信息
-            WatchFsUser user = selectWatchFsUserByDeviceIdAndUserId(deviceId, watchUserId, 0);
-            if (user != null) {
-                BeanUtils.copyProperties(user, appFsUserVo);
-                if (user.getBirthday() != null) {
-                    //计算年龄
-                    appFsUserVo.setAge(getAge(user.getBirthday()));
+            if (isFamily) {
+                WatchFamilyUserVo familyUser = watchFamilyUserService.selectWatchFamilyUserByDeviceId(deviceId, watchUserId);
+                if (familyUser != null) {
+                    BeanUtils.copyProperties(familyUser, appFsUserVo);
+                    if (familyUser.getBirthday() != null) {
+                        appFsUserVo.setAge(getAge(familyUser.getBirthday()));
+                    }
+                }
+            } else {
+                //根据设备id获取用户信息
+                WatchFsUser user = selectWatchFsUserByDeviceIdAndUserId(deviceId, watchUserId, 0);
+                if (user != null) {
+                    BeanUtils.copyProperties(user, appFsUserVo);
+                    if (user.getBirthday() != null) {
+                        //计算年龄
+                        appFsUserVo.setAge(getAge(user.getBirthday()));
+                    }
                 }
             }
-        }
 
-        return appFsUserVo;
+            return appFsUserVo;
+        }
     }
 
     private static int getAge(Date birthDate) {

+ 23 - 0
fs-service/src/main/java/com/fs/watch/task/HealthCheckTask.java

@@ -0,0 +1,23 @@
+package com.fs.watch.task;
+
+import java.util.List;
+import java.util.Map;
+import java.util.function.Supplier;
+
+public class HealthCheckTask {
+    private final String type;
+    private final Supplier<List<Map<String, Object>>> queryFunction;
+
+    public HealthCheckTask(String type, Supplier<List<Map<String, Object>>> queryFunction) {
+        this.type = type;
+        this.queryFunction = queryFunction;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public List<Map<String, Object>> query() {
+        return queryFunction.get();
+    }
+}

+ 207 - 0
fs-service/src/main/java/com/fs/watch/utils/AudioConvertUtil.java

@@ -0,0 +1,207 @@
+package com.fs.watch.utils;
+
+import com.fs.system.oss.CloudStorageService;
+import com.fs.system.oss.OSSFactory;
+
+import java.io.*;
+import java.nio.ByteBuffer;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+//import static sun.misc.IOUtils.readNBytes;
+
+public class AudioConvertUtil {
+
+    // 之前的方法 convertHardwareCompatibleAudio、uploadFileToCOS 等假设已经存在
+
+    /**
+     * 转换wav到硬件兼容 opuswb,上传到 COS,并删除临时文件
+     *
+     * @param inputWavPath wav 文件路径
+     * @param deviceId 设备ID,用于命名
+     * @param recordTime 录音时间字符串 "yyyy-MM-dd HH:mm:ss"
+     * @param audioBasePath 本地生成音频文件根目录
+     * @return 上传后的 COS URL
+     * @throws Exception 转换或上传失败抛出异常
+     */
+    public static String convertUploadAndClean(
+            String inputWavPath,
+            String deviceId,
+            String recordTime,
+            String audioBasePath) throws Exception {
+
+        // 1. 转换生成硬件兼容 opuswb 文件路径
+        String outputOpuswbPath = convertHardwareCompatibleAudio(inputWavPath, deviceId, recordTime, audioBasePath);
+
+        // 2. 计算上传到云存储的路径 cosPath
+        String datePart = recordTime.substring(0, 10); // 例如 "2025-07-22"
+        String[] ymd = datePart.split("-"); // ["2025", "07", "22"]
+
+        String fileName = deviceId + "-" +
+                recordTime.substring(11, 13) +
+                recordTime.substring(14, 16) +
+                recordTime.substring(17, 19) +
+                ".opuswb";
+
+        String cosPath = String.format("sendAudio/%s%s%s/%s", ymd[0],ymd[1], ymd[2], fileName);
+
+        // 3. 上传文件到云存储
+        try (InputStream inputStream = new FileInputStream(outputOpuswbPath)) {
+            CloudStorageService storage = OSSFactory.build();
+            storage.upload(inputStream, cosPath);
+        }
+
+        // 4. 删除本地临时文件
+        File tempFile = new File(outputOpuswbPath);
+        if (tempFile.exists() && !tempFile.delete()) {
+            System.err.println("临时文件删除失败:" + outputOpuswbPath);
+        }
+
+        // 5. 构造并返回访问URL,示例写法请根据你实际域名修改
+        return "https://cos.his.cdwjyyh.com/" + cosPath;
+    }
+
+
+
+    public static String convertHardwareCompatibleAudio(
+            String inputWavPath, String deviceId, String recordTime, String audioBasePath) throws Exception {
+
+        String subdir = recordTime.substring(0, 10);
+        String dirPath = Paths.get(audioBasePath, subdir).toString();
+        Files.createDirectories(Paths.get(dirPath));
+
+        String fileTimePart = recordTime.substring(11, 13) + recordTime.substring(14, 16) + recordTime.substring(17, 19);
+        String outputOpusFile = Paths.get(dirPath, deviceId + "-" + fileTimePart + ".opus").toString();
+        convertWavToOpus(inputWavPath, outputOpusFile);
+
+        String hardwareOpusFile = Paths.get(dirPath, deviceId + "-" + fileTimePart + ".opuswb").toString();
+        File hwOpus = new File(hardwareOpusFile);
+        if (hwOpus.exists()) hwOpus.delete();
+
+        decodeOggOpusToRawOpus(new File(outputOpusFile), hwOpus);
+
+        return hardwareOpusFile;
+    }
+
+    public static void convertWavToOpus(String inputWavPath, String outputOpusPath) throws IOException, InterruptedException {
+        File outputFile = new File(outputOpusPath);
+        if (outputFile.exists()) {
+            outputFile.delete();
+        }
+        List<String> command = Arrays.asList(
+                "ffmpeg",
+                "-i", inputWavPath,
+                "-c:a", "libopus",
+                "-b:a", "16k",
+                "-ar", "16000",
+                "-ac", "1",
+                "-vbr", "off",
+                "-frame_duration", "20",
+                "-application", "voip",
+                outputOpusPath
+        );
+        ProcessBuilder pb = new ProcessBuilder(command);
+        Process process = pb.start();
+        int exitCode = process.waitFor();
+        if (exitCode != 0) {
+            try (BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
+                String line;
+                while ((line = errorReader.readLine()) != null) {
+                    System.err.println(line);
+                }
+            }
+            throw new RuntimeException("ffmpeg 转码失败");
+        }
+    }
+
+    public static void decodeOggOpusToRawOpus(File inputFile, File outputFile) throws IOException {
+        try (InputStream in = new FileInputStream(inputFile);
+             OutputStream out = new FileOutputStream(outputFile)) {
+
+            int packetsSkipped = 0;
+            byte[] headerBuf = new byte[27];
+            while (true) {
+                int readBytes = in.read(headerBuf);
+                if (readBytes < 27) break;
+
+                if (!(headerBuf[0] == 'O' && headerBuf[1] == 'g' && headerBuf[2] == 'g' && headerBuf[3] == 'S')) {
+                    throw new IOException("Invalid Ogg file");
+                }
+
+                int segments = headerBuf[26] & 0xFF;
+                byte[] lacingValues = new byte[segments];
+                if (in.read(lacingValues) < segments) break;
+
+                List<Integer> packetSizes = new ArrayList<>();
+                int currentSize = 0;
+                for (byte b : lacingValues) {
+                    currentSize += (b & 0xFF);
+                    if ((b & 0xFF) < 255) {
+                        packetSizes.add(currentSize);
+                        currentSize = 0;
+                    }
+                }
+
+                for (int size : packetSizes) {
+                    byte[] packet = readNBytes(in,size);
+
+                    if (packetsSkipped < 2) {
+                        packetsSkipped++;
+                        continue;
+                    }
+
+                    out.write(ByteBuffer.allocate(4).putInt(size).array());
+                    out.write(ByteBuffer.allocate(4).putInt(size).array());
+                    out.write(packet);
+                }
+            }
+        }
+    }
+
+    /**
+     * 从输入流中读取最多 len 个字节,返回读取到的字节数组(等价于 readNBytes)
+     * @param in 输入流(如 FileInputStream、ByteArrayInputStream)
+     * @param len 要读取的最大字节数
+     * @return 实际读取到的字节数组
+     * @throws IOException 读取 IO 异常
+     */
+    public static byte[] readNBytes(InputStream in, int len) throws IOException {
+        // 参数合法性校验
+        if (len < 0) {
+            throw new IllegalArgumentException("读取字节长度不能为负数");
+        }
+        if (in == null) {
+            throw new NullPointerException("输入流不能为 null");
+        }
+
+        byte[] buffer = new byte[len];
+        int totalReadBytes = 0; // 累计已读取的字节数
+
+        // 循环读取,直到读取到指定长度或输入流结束
+        while (totalReadBytes < len) {
+            // 每次读取剩余未完成的字节数
+            int readBytes = in.read(buffer, totalReadBytes, len - totalReadBytes);
+
+            // 输入流已到达末尾(返回 -1),终止循环
+            if (readBytes == -1) {
+                break;
+            }
+
+            totalReadBytes += readBytes;
+        }
+
+        // 若实际读取的字节数小于指定长度,截取有效字节数组返回
+        if (totalReadBytes < len) {
+            byte[] result = new byte[totalReadBytes];
+            System.arraycopy(buffer, 0, result, 0, totalReadBytes);
+            return result;
+        }
+
+        return buffer;
+    }
+
+}
+

+ 53 - 0
fs-service/src/main/java/com/fs/watch/utils/MD5Utils.java

@@ -0,0 +1,53 @@
+package com.fs.watch.utils;
+
+import com.alibaba.fastjson.JSONObject;
+
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.net.URL;
+import java.security.MessageDigest;
+
+public class MD5Utils {
+    public static String  getFileMD5FromURL(String fileUrl) {
+        try (InputStream is = new URL(fileUrl).openStream()) {
+            MessageDigest md = MessageDigest.getInstance("MD5");
+            byte[] buffer = new byte[8192];
+            int bytesRead;
+
+            while ((bytesRead = is.read(buffer)) != -1) {
+                md.update(buffer, 0, bytesRead);
+            }
+
+            byte[] digest = md.digest();
+            // 转换为 32 位小写十六进制字符串
+            return String.format("%032x", new BigInteger(1, digest));
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    // 计算文件 MD5 并返回字节数和 MD5 值
+    public static JSONObject getMd5AndSizeFromUrl(String fileUrl) {
+        JSONObject result = new JSONObject();
+        try (InputStream is = new URL(fileUrl).openStream()) {
+            MessageDigest md = MessageDigest.getInstance("MD5");
+            byte[] buffer = new byte[8192];
+            int bytesRead;
+            long totalSize = 0;
+
+            while ((bytesRead = is.read(buffer)) != -1) {
+                md.update(buffer, 0, bytesRead);
+                totalSize += bytesRead;
+            }
+
+            byte[] digest = md.digest();
+            String md5 = String.format("%032x", new BigInteger(1, digest));
+            result.put("md5", md5);
+            result.put("size", totalSize);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return result;
+    }
+}

+ 42 - 12
fs-service/src/main/java/com/fs/watch/utils/MyHttpUtils.java

@@ -173,7 +173,8 @@ public class MyHttpUtils {
         //创建post方式请求对象
         HttpPost httpPost = new HttpPost(path);
         //创建httpclient对象
-        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
+        CloseableHttpClient httpClient = HttpClients.createDefault();
+        try {
             Map<String, Object> resMap = getObjectMap(params, httpPost, httpClient);
             if ((int) resMap.get("ReturnCode") == 0) {
                 return JSONObject.parseObject(resMap.get("Data").toString(), HashMap.class);
@@ -181,9 +182,15 @@ public class MyHttpUtils {
                 return null;
             }
         } catch (Exception e) {
-            System.out.println(e.getMessage());
+
+        } finally {
+            //释放连接
+            try {
+                httpClient.close();
+            } catch (Exception e) {
+
+            }
         }
-        //释放连接
         return null;
     }
 
@@ -194,20 +201,29 @@ public class MyHttpUtils {
         //创建post方式请求对象
         HttpPost httpPost = new HttpPost(path);
         //创建httpclient对象
-        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
+        CloseableHttpClient httpClient = HttpClients.createDefault();
+        try {
             Map<String, Object> resMap = getObjectMap(params, httpPost, httpClient);
             if ((int) resMap.get("ReturnCode") == 0) {
                 if (resMap.get("Data") == null) {
                     return JSONObject.parseObject(resMap.get("data").toString(), HashMap.class);
                 }
                 return JSONObject.parseObject(resMap.get("Data").toString(), HashMap.class);
+            } else if (Integer.parseInt(resMap.get("ReturnCode").toString()) == 10403 && "the device_id not belong to you".equals(resMap.get("message").toString())){
+                return resMap;
             } else {
                 return null;
             }
         } catch (Exception e) {
-            System.out.println(e.getMessage());
+            log.info(e.getMessage());
+        } finally {
+            //释放连接
+            try {
+                httpClient.close();
+            } catch (Exception e) {
+
+            }
         }
-        //释放连接
         return null;
     }
 
@@ -219,7 +235,8 @@ public class MyHttpUtils {
         //创建post方式请求对象
         HttpPost httpPost = new HttpPost(path);
         //创建httpclient对象
-        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
+        CloseableHttpClient httpClient = HttpClients.createDefault();
+        try {
             BasicResponseHandler handler = new BasicResponseHandler();
             //设置请求格式
             String jsonData = JSONObject.toJSONString(params);
@@ -232,9 +249,15 @@ public class MyHttpUtils {
             Map<String, Object> resMap = JSONObject.parseObject(result, HashMap.class);
             return resMap;
         } catch (Exception e) {
-            System.out.println(e.getMessage());
+
+        } finally {
+            //释放连接
+            try {
+                httpClient.close();
+            } catch (Exception e) {
+
+            }
         }
-        //释放连接
         return null;
     }
 
@@ -244,7 +267,8 @@ public class MyHttpUtils {
         //创建post方式请求对象
         HttpDelete httpDelete = new HttpDelete(path);
         // 创建HTTP客户端
-        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
+        CloseableHttpClient httpClient = HttpClients.createDefault();
+        try {
 //            BasicResponseHandler handler = new BasicResponseHandler();
 //            //设置请求格式
 //            String jsonData = JSONObject.toJSONString(params);
@@ -259,9 +283,15 @@ public class MyHttpUtils {
             result.put("message", responseBody.get("msg"));
             return result;
         } catch (Exception e) {
-            System.out.println(e.getMessage());
+
+        } finally {
+            //释放连接
+            try {
+                httpClient.close();
+            } catch (Exception e) {
+
+            }
         }
-        //释放连接
         return null;
     }
 

+ 11 - 0
fs-service/src/main/resources/application-config-druid-jnmy.yml

@@ -98,9 +98,20 @@ ipad:
   voiceApi: http://139.186.176.122:8009
   commonApi: http://139.186.176.122:7771
   watchUrl: https://manwatch.ylrzcloud.com/prod-api
+  wxIpadUrl:
   fsCompanyId: 13
 wx_miniapp_temp:
   pay_order_temp_id: -SjnK9K6cNKASa6AD9Q_c0YT7J1lPTEpPIpqbMJF8F0
   inquiry_temp_id: hwFXVh0AWqeasBsZpa0-urb3CrPeYEwBiy3P6AMMGFQ
 
+sysconfig:
+  # 包含哪些关键词的配置文件参数,将会被mask打码隐藏
+  hidden-key-list: api/app/token/key/secret/access
+  # 是否开启敏感参数隐藏功能
+  hide-secret: false
+  # 系统版本号
+  sysVersion:
+  # 是否开启登陆时选择业务组
+  show-dynamic-groupid: false
+
 

+ 136 - 0
fs-service/src/main/resources/mapper/his/FsHealthPulseMapper.xml

@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fs.his.mapper.FsHealthPulseMapper">
+
+    <resultMap type="FsHealthPulse" id="FsHealthPulseResult">
+        <result property="id"    column="id"    />
+        <result property="userId"    column="user_id"    />
+        <result property="name"    column="name"    />
+        <result property="sex"    column="sex"    />
+        <result property="age"    column="age"    />
+        <result property="status"    column="status"    />
+        <result property="leftHandResult"    column="left_hand_result"    />
+        <result property="rightHandResult"    column="right_hand_result"    />
+        <result property="pulseSummary"    column="pulse_summary"    />
+        <result property="pulseSuggestions"    column="pulse_suggestions"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="remark"    column="remark"    />
+        <result property="measureId"    column="measure_id"    />
+        <result property="pulseUrl"    column="pulse_url"    />
+    </resultMap>
+
+    <sql id="selectFsHealthPulseVo">
+        select id, user_id, name, sex, age, status, left_hand_result, right_hand_result, pulse_summary, pulse_suggestions, create_time, remark, measure_id,pulse_url from fs_health_pulse
+    </sql>
+
+    <select id="selectFsHealthPulseList" parameterType="FsHealthPulse" resultMap="FsHealthPulseResult">
+        <include refid="selectFsHealthPulseVo"/>
+        <where>
+            <if test="userId != null "> and user_id = #{userId}</if>
+            <if test="name != null  and name != ''"> and name like concat('%', #{name}, '%')</if>
+            <if test="sex != null "> and sex = #{sex}</if>
+            <if test="age != null "> and age = #{age}</if>
+            <if test="status != null "> and status = #{status}</if>
+            <if test="leftHandResult != null  and leftHandResult != ''"> and left_hand_result = #{leftHandResult}</if>
+            <if test="rightHandResult != null  and rightHandResult != ''"> and right_hand_result = #{rightHandResult}</if>
+            <if test="pulseSummary != null  and pulseSummary != ''"> and pulse_summary = #{pulseSummary}</if>
+            <if test="pulseSuggestions != null  and pulseSuggestions != ''"> and pulse_suggestions = #{pulseSuggestions}</if>
+            <if test="measureId != null  and measureId != ''"> and measure_id = #{measureId}</if>
+            <if test="pulseUrl != null  and pulseUrl != ''"> and pulse_url = #{pulseUrl}</if>
+        </where>
+    </select>
+
+    <select id="selectFsHealthPulseById" parameterType="Long" resultMap="FsHealthPulseResult">
+        <include refid="selectFsHealthPulseVo"/>
+        where id = #{id}
+    </select>
+    <select id="selectFsHealthPulseListVO" resultType="com.fs.his.vo.FsHealthPulseListVO">
+        select  * from fs_health_pulse where user_id=#{userId}
+        <if test="createDay != null and createDay !=''">
+            AND DATE(create_time) = #{createDay}
+        </if>
+        order by create_time desc
+    </select>
+    <select id="selectListByDateAndUserId" resultType="java.lang.String">
+        select DATE(create_time) from fs_health_pulse
+        <where>
+            <if test="startDate != null">
+                and create_time <![CDATA[>=]]> #{startDate}
+            </if>
+            <if test="endDate != null">
+                and create_time <![CDATA[<=]]> #{endDate}
+            </if>
+            <if test="userId != null">
+                and user_id= #{userId}
+            </if>
+        </where>
+        GROUP BY DATE(create_time)
+    </select>
+
+    <insert id="insertFsHealthPulse" parameterType="FsHealthPulse" useGeneratedKeys="true" keyProperty="id">
+        insert into fs_health_pulse
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="userId != null">user_id,</if>
+            <if test="name != null">name,</if>
+            <if test="sex != null">sex,</if>
+            <if test="age != null">age,</if>
+            <if test="status != null">status,</if>
+            <if test="leftHandResult != null">left_hand_result,</if>
+            <if test="rightHandResult != null">right_hand_result,</if>
+            <if test="pulseSummary != null">pulse_summary,</if>
+            <if test="pulseSuggestions != null">pulse_suggestions,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="remark != null">remark,</if>
+            <if test="measureId != null">measure_id,</if>
+            <if test="pulseUrl != null">pulse_url,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="userId != null">#{userId},</if>
+            <if test="name != null">#{name},</if>
+            <if test="sex != null">#{sex},</if>
+            <if test="age != null">#{age},</if>
+            <if test="status != null">#{status},</if>
+            <if test="leftHandResult != null">#{leftHandResult},</if>
+            <if test="rightHandResult != null">#{rightHandResult},</if>
+            <if test="pulseSummary != null">#{pulseSummary},</if>
+            <if test="pulseSuggestions != null">#{pulseSuggestions},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="remark != null">#{remark},</if>
+            <if test="measureId != null">#{measureId},</if>
+            <if test="pulseUrl != null">#{pulseUrl},</if>
+         </trim>
+    </insert>
+
+    <update id="updateFsHealthPulse" parameterType="FsHealthPulse">
+        update fs_health_pulse
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="userId != null">user_id = #{userId},</if>
+            <if test="name != null">name = #{name},</if>
+            <if test="sex != null">sex = #{sex},</if>
+            <if test="age != null">age = #{age},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="leftHandResult != null">left_hand_result = #{leftHandResult},</if>
+            <if test="rightHandResult != null">right_hand_result = #{rightHandResult},</if>
+            <if test="pulseSummary != null">pulse_summary = #{pulseSummary},</if>
+            <if test="pulseSuggestions != null">pulse_suggestions = #{pulseSuggestions},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="remark != null">remark = #{remark},</if>
+            <if test="measureId != null">measure_id = #{measureId},</if>
+            <if test="pulseUrl != null">pulse_url = #{pulseUrl},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteFsHealthPulseById" parameterType="Long">
+        delete from fs_health_pulse where id = #{id}
+    </delete>
+
+    <delete id="deleteFsHealthPulseByIds" parameterType="String">
+        delete from fs_health_pulse where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 148 - 0
fs-service/src/main/resources/mapper/his/FsHealthSurfaceMapper.xml

@@ -0,0 +1,148 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fs.his.mapper.FsHealthSurfaceMapper">
+
+    <resultMap type="FsHealthSurface" id="FsHealthSurfaceResult">
+        <result property="id"    column="id"    />
+        <result property="userId"    column="user_id"    />
+        <result property="name"    column="name"    />
+        <result property="sex"    column="sex"    />
+        <result property="age"    column="age"    />
+        <result property="status"    column="status"    />
+        <result property="surfaceUrl"    column="surface_url"    />
+        <result property="complexionResult"    column="complexion_result"    />
+        <result property="complexionTypes"    column="complexion_types"    />
+        <result property="spotProblems"    column="spot_problems"    />
+        <result property="swellingProblems"    column="swelling_problems"    />
+        <result property="glowResult"    column="glow_result"    />
+        <result property="diagnosisSummary"    column="diagnosis_summary"    />
+        <result property="healthSuggestions"    column="health_suggestions"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="remark"    column="remark"    />
+    </resultMap>
+
+    <sql id="selectFsHealthSurfaceVo">
+        select id, user_id, name, sex, age, status, surface_url, complexion_result, complexion_types, spot_problems, swelling_problems, glow_result, diagnosis_summary, health_suggestions,create_time,remark from fs_health_surface
+    </sql>
+
+    <select id="selectFsHealthSurfaceList" parameterType="FsHealthSurface" resultMap="FsHealthSurfaceResult">
+        <include refid="selectFsHealthSurfaceVo"/>
+        <where>
+            <if test="userId != null "> and user_id = #{userId}</if>
+            <if test="name != null  and name != ''"> and name like concat('%', #{name}, '%')</if>
+            <if test="sex != null "> and sex = #{sex}</if>
+            <if test="age != null "> and age = #{age}</if>
+            <if test="status != null "> and status = #{status}</if>
+            <if test="surfaceUrl != null  and surfaceUrl != ''"> and surface_url = #{surfaceUrl}</if>
+            <if test="complexionResult != null  and complexionResult != ''"> and complexion_result = #{complexionResult}</if>
+            <if test="complexionTypes != null  and complexionTypes != ''"> and complexion_types = #{complexionTypes}</if>
+            <if test="spotProblems != null  and spotProblems != ''"> and spot_problems = #{spotProblems}</if>
+            <if test="swellingProblems != null  and swellingProblems != ''"> and swelling_problems = #{swellingProblems}</if>
+            <if test="glowResult != null  and glowResult != ''"> and glow_result = #{glowResult}</if>
+            <if test="diagnosisSummary != null  and diagnosisSummary != ''"> and diagnosis_summary = #{diagnosisSummary}</if>
+            <if test="healthSuggestions != null  and healthSuggestions != ''"> and health_suggestions = #{healthSuggestions}</if>
+            <if test="createTime != null  and createTime != ''"> and create_time = #{createTime}</if>
+            <if test="remark != null  and remark != ''"> and remark = #{remark}</if>
+        </where>
+    </select>
+
+    <select id="selectFsHealthSurfaceById" parameterType="Long" resultMap="FsHealthSurfaceResult">
+        <include refid="selectFsHealthSurfaceVo"/>
+        where id = #{id}
+    </select>
+    <select id="selectFsHealthSurfaceListVO" resultType="com.fs.his.vo.FsHealthSurfaceListVO">
+        select  * from fs_health_surface where user_id=#{userId}
+        <if test="createDay != null and createDay !=''">
+            AND DATE(create_time) = #{createDay}
+        </if>
+        order by create_time desc
+    </select>
+    <select id="selectListByDateAndUserId" resultType="java.lang.String">
+        select DATE(create_time) from fs_health_surface
+        <where>
+            <if test="startDate != null">
+                and create_time <![CDATA[>=]]> #{startDate}
+            </if>
+            <if test="endDate != null">
+                and create_time <![CDATA[<=]]> #{endDate}
+            </if>
+            <if test="userId != null">
+                and user_id= #{userId}
+            </if>
+        </where>
+        GROUP BY DATE(create_time)
+    </select>
+
+    <insert id="insertFsHealthSurface" parameterType="FsHealthSurface" useGeneratedKeys="true" keyProperty="id">
+        insert into fs_health_surface
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="userId != null">user_id,</if>
+            <if test="name != null">name,</if>
+            <if test="sex != null">sex,</if>
+            <if test="age != null">age,</if>
+            <if test="status != null">status,</if>
+            <if test="surfaceUrl != null">surface_url,</if>
+            <if test="complexionResult != null">complexion_result,</if>
+            <if test="complexionTypes != null">complexion_types,</if>
+            <if test="spotProblems != null">spot_problems,</if>
+            <if test="swellingProblems != null">swelling_problems,</if>
+            <if test="glowResult != null">glow_result,</if>
+            <if test="diagnosisSummary != null">diagnosis_summary,</if>
+            <if test="healthSuggestions != null">health_suggestions,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="remark != null">remark,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="userId != null">#{userId},</if>
+            <if test="name != null">#{name},</if>
+            <if test="sex != null">#{sex},</if>
+            <if test="age != null">#{age},</if>
+            <if test="status != null">#{status},</if>
+            <if test="surfaceUrl != null">#{surfaceUrl},</if>
+            <if test="complexionResult != null">#{complexionResult},</if>
+            <if test="complexionTypes != null">#{complexionTypes},</if>
+            <if test="spotProblems != null">#{spotProblems},</if>
+            <if test="swellingProblems != null">#{swellingProblems},</if>
+            <if test="glowResult != null">#{glowResult},</if>
+            <if test="diagnosisSummary != null">#{diagnosisSummary},</if>
+            <if test="healthSuggestions != null">#{healthSuggestions},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="remark != null">#{remark},</if>
+         </trim>
+    </insert>
+
+    <update id="updateFsHealthSurface" parameterType="FsHealthSurface">
+        update fs_health_surface
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="userId != null">user_id = #{userId},</if>
+            <if test="name != null">name = #{name},</if>
+            <if test="sex != null">sex = #{sex},</if>
+            <if test="age != null">age = #{age},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="surfaceUrl != null">surface_url = #{surfaceUrl},</if>
+            <if test="complexionResult != null">complexion_result = #{complexionResult},</if>
+            <if test="complexionTypes != null">complexion_types = #{complexionTypes},</if>
+            <if test="spotProblems != null">spot_problems = #{spotProblems},</if>
+            <if test="swellingProblems != null">swelling_problems = #{swellingProblems},</if>
+            <if test="glowResult != null">glow_result = #{glowResult},</if>
+            <if test="diagnosisSummary != null">diagnosis_summary = #{diagnosisSummary},</if>
+            <if test="healthSuggestions != null">health_suggestions = #{healthSuggestions},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="remark != null">remark = #{remark},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteFsHealthSurfaceById" parameterType="Long">
+        delete from fs_health_surface where id = #{id}
+    </delete>
+
+    <delete id="deleteFsHealthSurfaceByIds" parameterType="String">
+        delete from fs_health_surface where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 124 - 0
fs-service/src/main/resources/mapper/his/FsUserAdditionalDataMapper.xml

@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fs.his.mapper.FsUserAdditionalDataMapper">
+
+    <resultMap type="FsUserAdditionalData" id="FsUserAdditionalDataResult">
+        <result property="id"    column="id"    />
+        <result property="fsUserId"    column="fs_user_id"    />
+        <result property="height"    column="height"    />
+        <result property="weight"    column="weight"    />
+        <result property="age"    column="age"    />
+        <result property="sex"    column="sex"    />
+        <result property="previousMedicalHistory"    column="previous_medical_history"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="status"    column="status"    />
+        <result property="remark"    column="remark"    />
+        <result property="username"    column="username"    />
+        <result property="phone"    column="phone"    />
+        <result property="historyOfAllergies"    column="history_of_allergies"    />
+        <result property="habit"    column="habit"    />
+        <result property="idCard"    column="id_card"    />
+        <result property="consultationRecord"    column="consultation_record"    />
+    </resultMap>
+
+    <sql id="selectFsUserAdditionalDataVo">
+        select id, fs_user_id, height, weight, age, sex, previous_medical_history, create_time, status, remark,username,phone,history_of_allergies,habit,id_card,consultation_record from fs_user_additional_data
+    </sql>
+
+    <select id="selectFsUserAdditionalDataList" parameterType="FsUserAdditionalData" resultMap="FsUserAdditionalDataResult">
+        <include refid="selectFsUserAdditionalDataVo"/>
+        <where>
+            <if test="fsUserId != null "> and fs_user_id = #{fsUserId}</if>
+            <if test="height != null  and height != ''"> and height = #{height}</if>
+            <if test="weight != null  and weight != ''"> and weight = #{weight}</if>
+            <if test="age != null  and age != ''"> and age = #{age}</if>
+            <if test="sex != null "> and sex = #{sex}</if>
+            <if test="previousMedicalHistory != null  and previousMedicalHistory != ''"> and previous_medical_history = #{previousMedicalHistory}</if>
+            <if test="status != null "> and status = #{status}</if>
+            <if test="username != null "> and username = #{username}</if>
+            <if test="phone != null "> and phone = #{phone}</if>
+            <if test="historyOfAllergies != null "> and history_of_allergies = #{historyOfAllergies}</if>
+            <if test="habit != null "> and habit = #{habit}</if>
+            <if test="idCard != null "> and id_card = #{idCard}</if>
+            <if test="consultationRecord != null "> and consultation_record = #{consultationRecord}</if>
+        </where>
+    </select>
+
+    <select id="selectFsUserAdditionalDataById" parameterType="Long" resultMap="FsUserAdditionalDataResult">
+        <include refid="selectFsUserAdditionalDataVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertFsUserAdditionalData" parameterType="FsUserAdditionalData" useGeneratedKeys="true" keyProperty="id">
+        insert into fs_user_additional_data
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="fsUserId != null">fs_user_id,</if>
+            <if test="height != null">height,</if>
+            <if test="weight != null">weight,</if>
+            <if test="age != null">age,</if>
+            <if test="sex != null">sex,</if>
+            <if test="previousMedicalHistory != null">previous_medical_history,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="status != null">status,</if>
+            <if test="remark != null">remark,</if>
+            <if test="username != null">username,</if>
+            <if test="phone != null">phone,</if>
+            <if test="historyOfAllergies != null">history_of_allergies,</if>
+            <if test="habit != null">habit,</if>
+            <if test="idCard != null">id_card,</if>
+            <if test="consultationRecord != null">consultation_record,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="fsUserId != null">#{fsUserId},</if>
+            <if test="height != null">#{height},</if>
+            <if test="weight != null">#{weight},</if>
+            <if test="age != null">#{age},</if>
+            <if test="sex != null">#{sex},</if>
+            <if test="previousMedicalHistory != null">#{previousMedicalHistory},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="status != null">#{status},</if>
+            <if test="remark != null">#{remark},</if>
+            <if test="username != null">#{username},</if>
+            <if test="phone != null">#{phone},</if>
+            <if test="historyOfAllergies != null">#{historyOfAllergies},</if>
+            <if test="habit != null">#{habit},</if>
+            <if test="idCard != null">#{idCard},</if>
+            <if test="consultationRecord != null">#{consultationRecord},</if>
+         </trim>
+    </insert>
+
+    <update id="updateFsUserAdditionalData" parameterType="FsUserAdditionalData">
+        update fs_user_additional_data
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="fsUserId != null">fs_user_id = #{fsUserId},</if>
+            <if test="height != null">height = #{height},</if>
+            <if test="weight != null">weight = #{weight},</if>
+            <if test="age != null">age = #{age},</if>
+            <if test="sex != null">sex = #{sex},</if>
+            <if test="previousMedicalHistory != null">previous_medical_history = #{previousMedicalHistory},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="remark != null">remark = #{remark},</if>
+            <if test="username != null">remark = #{username},</if>
+            <if test="phone != null">phone = #{phone},</if>
+            <if test="historyOfAllergies != null">history_of_allergies = #{historyOfAllergies},</if>
+            <if test="habit != null">habit = #{habit},</if>
+            <if test="idCard != null">id_card = #{idCard},</if>
+            <if test="consultationRecord != null">consultation_record = #{consultationRecord},</if>
+        </trim>
+        where fs_user_id = #{fsUserId}
+    </update>
+
+    <delete id="deleteFsUserAdditionalDataById" parameterType="Long">
+        delete from fs_user_additional_data where id = #{id}
+    </delete>
+
+    <delete id="deleteFsUserAdditionalDataByIds" parameterType="String">
+        delete from fs_user_additional_data where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>

+ 0 - 15
fs-service/src/main/resources/mapper/his/FsUserMapper.xml

@@ -2476,21 +2476,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         </foreach>
     </update>
 
-    <!-- 查询用户列表(用于积分管理) -->
-    <select id="selectFsUserListForIntegral" parameterType="FsUser" resultMap="FsUserResult">
-        select user_id, nick_name, phone, integral from fs_user
-        <where>
-            and is_del = 0
-            <if test="phone != null and phone != ''">
-                and phone like concat('%', #{phone}, '%')
-            </if>
-            <if test="nickName != null and nickName != ''">
-                and (nick_name like concat('%', #{nickName}, '%') or nickname like concat('%', #{nickName}, '%'))
-            </if>
-        </where>
-        order by user_id desc
-    </select>
-
     <!-- 查询企业微信外部联系人用户列表 -->
     <select id="selectFsUserListVOByExternalContact" resultType="com.fs.his.vo.FsUserVO">
         SELECT DISTINCT

+ 11 - 0
fs-service/src/main/resources/mapper/his/InterestAiChatSessionMapper.xml

@@ -136,6 +136,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         inner join fs_interest_ai_role t3 on t3.role_id = t2.role_id
         where t2.session_id = #{sessionId}
     </select>
+    <select id="selectSessionIdByUserAndRole" resultType="java.lang.Integer">
+        select session_id from fs_interest_ai_session where user_id = #{userId} and role_id = #{roleId} limit 1
+    </select>
+    <select id="selectSessionBySessionId" resultType="com.fs.his.domain.FsInterestAiSession">
+        select session_id,chat_id,user_id,role_id,role_name, status, nick_name,avatar,create_time,update_time
+        from fs_interest_ai_session where session_id = #{sessionId}
+    </select>
+    <select id="selectAiMsgBySessionIdAndMsg" resultType="java.lang.Integer">
+        <![CDATA[ select count(*) from fs_interest_ai_msg where session_id = #{param.sessionId} and content = #{param.message}
+                                                            and begin_time = #{param.beginTime}]]>
+    </select>
 
     <insert id="insertFsInterestAiSession" parameterType="FsInterestAiSession" useGeneratedKeys="true" keyProperty="sessionId">
         insert into fs_interest_ai_session

+ 9 - 0
fs-service/src/main/resources/mapper/watch/WatchDeviceInfoClicMapper.xml

@@ -177,6 +177,15 @@
         select * from watch.watch_device_info where sim1_iccid like #{iccid}
     </select>
 
+    <select id="selectListByIccList" resultType="com.fs.watch.domain.WatchDeviceInfoClic">
+        select * from watch.watch_device_info where
+        sim1_iccid
+        in
+        <foreach item="item" collection="iccidList"  separator="," open="(" close=")" >
+            #{item}
+        </foreach>
+    </select>
+
 
 </mapper>
 

+ 18 - 11
fs-watch/src/main/java/com/fs/app/controller/WatchController.java

@@ -647,7 +647,7 @@ public class WatchController extends AppBaseController {
             double latitude = Double.valueOf(loc.get(0));  // 北京的纬度
             double longitude = Double.valueOf(loc.get(1));  // 北京的经度
             if (latitude != 0.0 && longitude != 0.0) {
-                address = GeocodingUtils.getAddressFromLatLng(latitude, longitude);
+                address = GeocodingUtils.getAddressFromLatLng(longitude,latitude);
             }
         }
 
@@ -1341,8 +1341,17 @@ public class WatchController extends AppBaseController {
     @GetMapping("/queryHealthReport")
     public AjaxResult queryHealthReport(@RequestParam(value = "startTime") Date startTime,
                                         @RequestParam(value = "endTime") Date endTime,
-                                        @RequestParam(value = "deviceId") String deviceId) {
-        return AjaxResult.success(watchBasicInfoService.getAppFsUserHealthReportVo(startTime,endTime, deviceId));
+                                        @RequestParam(value = "deviceId",required = false) String deviceId,
+                                        @RequestParam(value = "isFamily",required = false) Boolean isFamily,
+                                        @RequestParam(value = "userId",required = false) Long userId,
+                                        @RequestParam(value = "isRefresh",required = false) Integer isRefresh) {
+        if (userId == null){
+            userId = Long.valueOf(getUserId());
+        }
+        if (isFamily == null){
+            isFamily = Boolean.FALSE;
+        }
+        return AjaxResult.success(watchBasicInfoService.getAppFsUserHealthReportVo(startTime,endTime, deviceId,userId,isFamily,isRefresh));
     }
 
     /**
@@ -1355,8 +1364,8 @@ public class WatchController extends AppBaseController {
      */
     @GetMapping("/fatigue/list")
     public AjaxResult queryFatigueByDate(@RequestParam(value = "startTime") Date startTime,
-                                         @RequestParam(value = "endTime") Date endTime,
-                                         @RequestParam(value = "deviceId") String deviceId) {
+                                       @RequestParam(value = "endTime") Date endTime,
+                                       @RequestParam(value = "deviceId") String deviceId) {
         return AjaxResult.success(watchFatigueDataService.list(startTime, endTime, deviceId));
     }
 
@@ -1371,8 +1380,8 @@ public class WatchController extends AppBaseController {
     @Login
     @GetMapping("/fatigue/count")
     public AjaxResult countFatigueByDate(@RequestParam(value = "startTime") Date startTime,
-                                         @RequestParam(value = "endTime") Date endTime,
-                                         @RequestParam(value = "deviceId") String deviceId) {
+                                       @RequestParam(value = "endTime") Date endTime,
+                                       @RequestParam(value = "deviceId") String deviceId) {
         return AjaxResult.success(watchFatigueDataService.countByDate(startTime, endTime, deviceId));
     }
 
@@ -1401,15 +1410,13 @@ public class WatchController extends AppBaseController {
     @ApiOperation("健康周报-步数,卡路里,睡眠")
     public AjaxResult getUserHealthInfoByDeviceId(@RequestParam(value = "startTime") Date startTime,
                                                   @RequestParam(value = "endTime") Date endTime,
-                                                  @RequestParam(value = "deviceId") String deviceId,
+                                                  @RequestParam(value = "deviceId",required = false) String deviceId,
                                                   @RequestParam(value = "userId",required = false) Long userId) {
-        if (com.fs.common.utils.StringUtils.isBlank(deviceId)) {
-            return null;
-        }
         if (userId == null){
             userId = Long.valueOf(getUserId());
         }
         return AjaxResult.success(watchSportDataService.getUserHealthInfoByDeviceId(deviceId,startTime,endTime,userId));
     }
 
+
 }

+ 20 - 12
fs-watch/src/main/java/com/fs/app/controller/WatchUserController.java

@@ -8,17 +8,16 @@ import com.fs.app.param.WatchUserEditParam;
 import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.domain.R;
 import com.fs.common.utils.DateUtils;
-import com.fs.his.domain.FsUserWatch;
-import com.fs.his.dto.FsStoreCartDTO;
-import com.fs.his.service.IFsUserService;
-import com.fs.his.service.IFsUserWatchService;
+import com.fs.his.domain.FsUserAdditionalData;
+import com.fs.his.service.IFsUserAdditionalDataService;
 import com.fs.his.utils.PhoneUtil;
 import com.fs.watch.domain.*;
 import com.fs.watch.domain.vo.AppFsUserVo;
+import com.fs.watch.domain.vo.WatchDeviceInfoVo;
 import com.fs.watch.domain.vo.WatchFamilyUserVo;
+import com.fs.watch.mapper.WatchDeviceInfoMapper;
 import com.fs.watch.param.WatchFamilyUserEditParam;
 import com.fs.watch.service.*;
-import com.fs.watch.service.impl.WatchDeviceDataServiceImpl;
 import io.swagger.annotations.ApiOperation;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.BeanUtils;
@@ -27,8 +26,10 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.stream.Collectors;
 
 /**
@@ -53,7 +54,8 @@ public class WatchUserController extends AppBaseController {
     private WatchDeviceDataService watchDeviceDataService;
     @Autowired
     private WatchDeviceInfoService deviceInfoService;
-
+    @Autowired
+    private IFsUserAdditionalDataService fsUserAdditionalDataService;
     /**
      * 获取用户信息
      *
@@ -82,7 +84,7 @@ public class WatchUserController extends AppBaseController {
                 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));
                     }
                 }
                 //处理deviceId
@@ -341,16 +343,22 @@ public class WatchUserController extends AppBaseController {
      */
     @GetMapping("/getUserByDeviceId")
     @ApiOperation("健康报告-个人信息")
-    public AjaxResult getUserByDeviceId(@RequestParam("deviceId") String deviceId,
+    public AjaxResult getUserByDeviceId(@RequestParam(value = "deviceId",required = false) String deviceId,
                                         @RequestParam("isFamily") Boolean isFamily,
                                         @RequestParam(value = "userId",required = false) Long userId) {
-        if (com.fs.common.utils.StringUtils.isBlank(deviceId)) {
-            return null;
-        }
         if (userId == null){
             userId = Long.valueOf(getUserId());
         }
-        return AjaxResult.success(userService.getUserInfoByDeviceId(deviceId, isFamily,userId));
+        AppFsUserVo userInfoByDeviceId = userService.getUserInfoByDeviceId(deviceId, isFamily, userId);
+        FsUserAdditionalData fsUserAdditionalData = fsUserAdditionalDataService.selectUserByUserId(userId);
+        if (fsUserAdditionalData != null){
+            userInfoByDeviceId.setAge(Integer.parseInt(fsUserAdditionalData.getAge()));
+            userInfoByDeviceId.setSex(fsUserAdditionalData.getSex());
+            userInfoByDeviceId.setPreviousMedicalHistory(fsUserAdditionalData.getPreviousMedicalHistory());
+            userInfoByDeviceId.setHeight(Integer.parseInt(fsUserAdditionalData.getHeight()));
+            userInfoByDeviceId.setWeight(Integer.parseInt(fsUserAdditionalData.getWeight()));
+        }
+        return AjaxResult.success(userInfoByDeviceId);
     }
 
 }

+ 5 - 4
fs-watch/src/main/java/com/fs/app/utils/JwtUtils.java

@@ -18,11 +18,12 @@ import java.util.Date;
 public class JwtUtils {
     private Logger logger = LoggerFactory.getLogger(getClass());
 
-
-    private String secret = "f4e2e52034348f86b67cde581c0f9eb5";
+    //private String secret = "f4e2e52034348f86b67cde581c0f9eb5";
+//    private String secret = "f4e2e52034348f86b68cde581c0f9eb5";
+    private String secret;
     private long expire;
-    //    private String header;
-    private String header = "AppToken";
+        private String header;
+//    private String header = "AppToken";
 
     /**
      * 生成jwt token

+ 15 - 7
fs-watch/src/main/java/com/fs/framework/config/DataSourceConfig.java

@@ -22,10 +22,9 @@ import java.util.Map;
 @Configuration
 public class DataSourceConfig {
 
-
     @Bean
-    @ConfigurationProperties(prefix = "spring.datasource.sop.druid.master")
-    public DataSource sopDataSource() {
+    @ConfigurationProperties(prefix = "spring.datasource.clickhouse")
+    public DataSource clickhouseDataSource() {
         return new DruidDataSource();
     }
 
@@ -35,21 +34,30 @@ public class DataSourceConfig {
         return new DruidDataSource();
     }
 
-
+    @Bean
+    @ConfigurationProperties(prefix = "spring.datasource.mysql.druid.slave")
+    public DataSource slaveDataSource() {
+        return new DruidDataSource();
+    }
 
     @Bean
     @Primary
-    public DynamicDataSource dataSource(@Qualifier("masterDataSource") DataSource masterDataSource, @Qualifier("sopDataSource") DataSource sopDataSource) {
+    public DynamicDataSource dataSource(@Qualifier("clickhouseDataSource") DataSource clickhouseDataSource,
+                                        @Qualifier("masterDataSource") DataSource masterDataSource,
+                                        @Qualifier("slaveDataSource") DataSource slaveDataSource) {
         Map<Object, Object> targetDataSources = new HashMap<>();
-        targetDataSources.put(DataSourceType.SOP.name(), sopDataSource);
+        targetDataSources.put(DataSourceType.MASTER, masterDataSource);
+        targetDataSources.put(DataSourceType.SLAVE, slaveDataSource);
+        targetDataSources.put(DataSourceType.CLICKHOUSE.name(), clickhouseDataSource); // Ensure matching key
         return new DynamicDataSource(masterDataSource, targetDataSources);
     }
+
     /**
      * 去除监控页面底部的广告
      */
     @SuppressWarnings({ "rawtypes", "unchecked" })
     @Bean
-    @ConditionalOnProperty(name = "spring.datasource.mysql.druid.statViewServlet.enabled", havingValue = "true")
+    @ConditionalOnProperty(name = "spring.datasource.druid.statViewServlet.enabled", havingValue = "true")
     public FilterRegistrationBean removeDruidFilterRegistrationBean(DruidStatProperties properties)
     {
         // 获取web监控页面的参数

+ 3 - 2
fs-watch/src/main/java/com/fs/framework/config/MyBatisConfig.java

@@ -1,9 +1,9 @@
 package com.fs.framework.config;
 
 import com.fs.common.utils.StringUtils;
+import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
 import org.apache.ibatis.io.VFS;
 import org.apache.ibatis.session.SqlSessionFactory;
-import org.mybatis.spring.SqlSessionFactoryBean;
 import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
@@ -123,7 +123,8 @@ public class MyBatisConfig
         typeAliasesPackage = setTypeAliasesPackage(typeAliasesPackage);
         VFS.addImplClass(SpringBootVFS.class);
 
-        final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
+        // 使用 MyBatis-Plus 的 SqlSessionFactoryBean,确保 BaseMapper 的通用方法(如 selectList)可用
+        final MybatisSqlSessionFactoryBean sessionFactory = new MybatisSqlSessionFactoryBean();
         sessionFactory.setDataSource(dataSource);
         sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
         sessionFactory.setMapperLocations(resolveMapperLocations(StringUtils.split(mapperLocations, ",")));

+ 5 - 14
fs-watch/src/main/java/com/fs/framework/config/RedisConfig.java

@@ -15,8 +15,6 @@ import org.springframework.data.redis.core.script.DefaultRedisScript;
 import org.springframework.data.redis.serializer.GenericToStringSerializer;
 import org.springframework.data.redis.serializer.StringRedisSerializer;
 
-import java.math.BigDecimal;
-
 /**
  * redis配置
  *
@@ -74,19 +72,16 @@ public class RedisConfig extends CachingConfigurerSupport
         RedisTemplate<String, Integer> template = new RedisTemplate<>();
         template.setConnectionFactory(connectionFactory);
 
-        // 使用StringRedisSerializer来序列化和反序列化redis的key值
         template.setKeySerializer(new StringRedisSerializer());
-
-        // 使用GenericToStringSerializer保证BigDecimal精度不丢失
         template.setValueSerializer(new GenericToStringSerializer<>(Integer.class));
 
-        // Hash的key也采用StringRedisSerializer的序列化方式
         template.setHashKeySerializer(new StringRedisSerializer());
         template.setHashValueSerializer(new GenericToStringSerializer<>(Integer.class));
 
         template.afterPropertiesSet();
         return template;
     }
+
     @Bean
     @SuppressWarnings(value = { "unchecked", "rawtypes" })
     public RedisTemplate<String, Object> redisTemplateForObject(RedisConnectionFactory connectionFactory) {
@@ -113,19 +108,15 @@ public class RedisConfig extends CachingConfigurerSupport
     }
 
     @Bean
-    public RedisTemplate<String, BigDecimal> redisTemplateForBigDecimal(RedisConnectionFactory connectionFactory) {
-        RedisTemplate<String, BigDecimal> template = new RedisTemplate<>();
+    public RedisTemplate<String, java.math.BigDecimal> redisTemplateForBigDecimal(RedisConnectionFactory connectionFactory) {
+        RedisTemplate<String, java.math.BigDecimal> template = new RedisTemplate<>();
         template.setConnectionFactory(connectionFactory);
 
-        // 使用StringRedisSerializer来序列化和反序列化redis的key值
         template.setKeySerializer(new StringRedisSerializer());
+        template.setValueSerializer(new GenericToStringSerializer<>(java.math.BigDecimal.class));
 
-        // 使用GenericToStringSerializer保证BigDecimal精度不丢失
-        template.setValueSerializer(new GenericToStringSerializer<>(BigDecimal.class));
-
-        // Hash的key也采用StringRedisSerializer的序列化方式
         template.setHashKeySerializer(new StringRedisSerializer());
-        template.setHashValueSerializer(new GenericToStringSerializer<>(BigDecimal.class));
+        template.setHashValueSerializer(new GenericToStringSerializer<>(java.math.BigDecimal.class));
 
         template.afterPropertiesSet();
         return template;

+ 3 - 0
fs-watch/src/main/java/com/fs/watch/controller/DeviceSetUpController.java

@@ -3,9 +3,11 @@ package com.fs.watch.controller;
 import com.fs.app.annotation.Login;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.redis.RedisCache;
 import com.fs.common.exception.ServiceException;
 import com.fs.common.utils.StringUtils;
 import com.fs.company.domain.CompanyUser;
+import com.fs.his.utils.RedisCacheUtil;
 import com.fs.watch.domain.*;
 import com.fs.watch.domain.vo.AlarmClockVos;
 import com.fs.watch.param.WatchSetUpSendParam;
@@ -14,6 +16,7 @@ import com.fs.watch.scheduled.DynamicSendStudyTask;
 import com.fs.watch.service.DeviceSetUpService;
 import com.fs.watch.service.WatchSendMsgSetService;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.connection.RedisServer;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;

+ 33 - 0
fs-watch/src/main/java/com/fs/watch/controller/WatchAudioDataController.java

@@ -0,0 +1,33 @@
+package com.fs.watch.controller;
+
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.watch.domain.WatchAudioMsgLog;
+import com.fs.watch.service.WatchAudioMsgLogService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+
+
+/**
+ * 设备语音表控制层
+ *
+ * @author makejava
+ * @since 2024-08-12 14:54:03
+ */
+@RestController
+@RequestMapping("/watch/audio")
+public class WatchAudioDataController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private WatchAudioMsgLogService watchAudioMsgLogService;
+
+    @PostMapping("/insert")
+    public AjaxResult insertAudioData(@RequestBody WatchAudioMsgLog data){
+        return AjaxResult.success(watchAudioMsgLogService.insert(data));
+    }
+
+}
+

+ 57 - 0
fs-watch/src/main/java/com/fs/watch/controller/WatchCommonController.java

@@ -0,0 +1,57 @@
+package com.fs.watch.controller;
+
+import com.fs.common.config.FSConfig;
+import com.fs.common.utils.StringUtils;
+import com.fs.common.utils.file.FileUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * @author MixLiu
+ * @date 2025/7/18 下午2:34)
+ */
+
+@RestController
+@RequestMapping("/watchCommon")
+public class WatchCommonController {
+
+    private static final Logger log = LoggerFactory.getLogger(WatchCommonController.class);
+    /**
+     * 通用下载请求
+     *
+     * @param fileName 文件名称
+     * @param delete 是否删除
+     */
+    @GetMapping("/download")
+    public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request)
+    {
+        try
+        {
+            if (!FileUtils.checkAllowDownload(fileName))
+            {
+                throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName));
+            }
+            String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
+            String filePath = FSConfig.getDownloadPath() + fileName;
+
+            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
+            FileUtils.setAttachmentResponseHeader(response, realFileName);
+            FileUtils.writeBytes(filePath, response.getOutputStream());
+            if (delete)
+            {
+                FileUtils.deleteFile(filePath);
+            }
+        }
+        catch (Exception e)
+        {
+            log.error("下载文件失败", e);
+        }
+    }
+}

+ 16 - 0
fs-watch/src/main/java/com/fs/watch/controller/WatchDeviceInfoClicController.java

@@ -3,12 +3,21 @@ package com.fs.watch.controller;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.utils.poi.ExcelUtil;
+import com.fs.crm.domain.CrmCustomerAssign;
+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.param.DeviceIdAndIotInfoQueryParam;
 import com.fs.watch.service.WatchDeviceInfoClicService;
+import com.fs.watch.utils.IotUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.List;
+
 @RestController
 @RequestMapping("/watch/deviceInfo")
 public class WatchDeviceInfoClicController extends BaseController {
@@ -27,4 +36,11 @@ public class WatchDeviceInfoClicController extends BaseController {
         startPage();
         return watchDeviceInfoClicService.getDeviceIdAndIotInfo(param);
     }
+    @GetMapping("/exportDeviceIdAndIotInfo")
+    public AjaxResult exportDeviceIdAndIotInfo(DeviceIdAndIotInfoQueryParam param){
+        List<WatchDeviceInfoAndIotExportVO> list  = watchDeviceInfoClicService.exportDeviceIdAndIotInfo(param);
+        ExcelUtil<WatchDeviceInfoAndIotExportVO> util = new ExcelUtil<WatchDeviceInfoAndIotExportVO>(WatchDeviceInfoAndIotExportVO.class);
+        return util.exportExcel(list, "设备网卡信息");
+    }
+
 }

+ 16 - 2
fs-watch/src/main/java/com/fs/watch/controller/WatchDeviceInfoController.java

@@ -4,6 +4,7 @@ import com.fs.app.annotation.Login;
 import com.fs.common.annotation.Log;
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.domain.R;
 import com.fs.common.core.page.TableDataInfo;
 import com.fs.common.enums.BusinessType;
 import com.fs.common.exception.ServiceException;
@@ -13,25 +14,33 @@ import com.fs.company.domain.CompanyUser;
 import com.fs.company.service.ICompanyRoleService;
 import com.fs.company.service.ICompanyService;
 import com.fs.company.service.ICompanyUserService;
+import com.fs.company.service.ICompanyUserUserService;
 import com.fs.his.param.FsHealthTongueListUParam;
 import com.fs.his.service.IFsHealthTongueService;
 import com.fs.his.vo.FsHealthTongueListUVO;
 import com.fs.system.service.ISysRoleService;
 import com.fs.watch.domain.WatchDeviceInfo;
+import com.fs.watch.domain.vo.AppFsUserHealthReportVo;
 import com.fs.watch.domain.vo.WatchDeviceInfoVo;
 import com.fs.watch.param.WatchDeviceInfoQueryParam;
 import com.fs.watch.service.WatchBasicInfoService;
 import com.fs.watch.service.WatchDataService;
 import com.fs.watch.service.WatchDeviceInfoService;
 import com.fs.watch.service.WatchUserService;
+import com.fs.watch.service.impl.WatchUserServiceImpl;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletRequest;
+import java.util.Arrays;
 import java.util.Date;
 import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
 
 
 @RestController
@@ -400,8 +409,13 @@ public class WatchDeviceInfoController extends BaseController {
     @GetMapping("/queryHealthReport")
     public AjaxResult queryHealthReport(@RequestParam(value = "startTime") Date startTime,
                                         @RequestParam(value = "endTime") Date endTime,
-                                        @RequestParam(value = "deviceId") String deviceId) {
-        return AjaxResult.success(watchBasicInfoService.getAppFsUserHealthReportVo(startTime,endTime, deviceId));
+                                        @RequestParam(value = "deviceId") String deviceId,
+                                        @RequestParam(value = "isFamily",required = false) Boolean isFamily,
+                                        @RequestParam(value = "userId",required = false) Long userId,
+                                        @RequestParam(value = "isRefresh",required = false) Integer isRefresh)
+    {
+        return AjaxResult.success(watchBasicInfoService.getAppFsUserHealthReportVo(startTime, endTime, deviceId, null, false,isRefresh==null?1:isRefresh));
+
     }
 
 

+ 4 - 0
fs-watch/src/main/java/com/fs/watch/controller/WatchFatigueDataController.java

@@ -2,12 +2,16 @@ package com.fs.watch.controller;
 
 import com.fs.common.core.controller.BaseController;
 import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.core.page.TableDataInfo;
 import com.fs.watch.domain.WatchFatigueData;
+import com.fs.watch.domain.WatchTemperatureData;
 import com.fs.watch.param.WatchDataQueryParam;
 import com.fs.watch.service.WatchFatigueDataService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.List;
+
 @RestController
 @RequestMapping("/watch/fatigue")
 public class WatchFatigueDataController extends BaseController {

+ 1 - 1
fs-watch/src/main/java/com/fs/watch/controller/WatchGetDataController.java

@@ -3,7 +3,7 @@ package com.fs.watch.controller;
 import com.fs.common.core.domain.AjaxResult;
 import com.fs.common.utils.StringUtils;
 import com.fs.watch.domain.WatchDeviceInfo;
-import com.fs.watch.service.WatchDeviceInfoService;
+import com.fs.watch.service.*;
 import io.swagger.annotations.Api;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;

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