Browse Source

浙一项目二期————传染病可视化(改)

chenbin 1 month ago
parent
commit
62980d2bd8

+ 41 - 0
src/main/java/com/qizhen/healsphere/repository/mapper/EpifluChineseQueryMapper.java

@@ -0,0 +1,41 @@
+package com.qizhen.healsphere.repository.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qizhen.healsphere.web.param.Epiflu;
+import com.qizhen.healsphere.web.vo.InputVO;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+@Mapper
+public interface EpifluChineseQueryMapper extends BaseMapper<Epiflu> {
+
+    /**
+     * 获取条件查询的条数
+     * @param inputVO 查询参数
+     * @return 符合条件的记录数
+     */
+    @Select("<script>" +
+            "SELECT COUNT(1) FROM epiflu " +
+            "WHERE 1=1 " +
+            "<if test='inputVO.subtype != null and !inputVO.subtype.isEmpty()'> " +
+            "AND subtype = #{inputVO.subtype} " +
+            "</if>" +
+            "<if test='inputVO.constellation != null and !inputVO.constellation.isEmpty()'> " +
+            "AND clade IN " +
+            "<foreach item='item' collection='inputVO.constellation' open='(' separator=',' close=')'>" +
+            "#{item}" +
+            "</foreach> " +
+            "</if>" +
+            "<if test='inputVO.isChina != null'> " +
+            "AND is_china = #{inputVO.isChina} " +
+            "</if>" +
+            "<if test='inputVO.startDate != null and inputVO.endDate != null'> " +
+            "AND collection_date BETWEEN #{inputVO.startDate} AND #{inputVO.endDate} " +
+            "</if>" +
+            "</script>")
+    int getCountByQuery(@Param("inputVO") InputVO inputVO);
+
+
+
+}

+ 31 - 1
src/main/java/com/qizhen/healsphere/repository/mapper/EpifluMapper.java

@@ -14,11 +14,13 @@ import java.util.Map;
 
 @Mapper
 public interface EpifluMapper extends BaseMapper<Epiflu> {
-    //获取subtype的列表
+    // 获取subtype的列表
     @Select("SELECT DISTINCT subtype FROM epiflu")
     List<String> findDistinctSubtype();
+
     @Select("SELECT DISTINCT clade FROM epiflu WHERE subtype = #{subtype}")
     List<String> findDistinctCladeBySubtype(@Param("subtype") String subtype);
+
     @Select("SELECT COUNT(1) FROM epiflu WHERE subtype = #{subtype}")
     Integer selectCountBySubtype(@Param("subtype") String subtype);
 
@@ -27,9 +29,20 @@ public interface EpifluMapper extends BaseMapper<Epiflu> {
 
     @Select("SELECT COUNT(1) FROM epiflu WHERE subtype = #{subtype} AND collection_date BETWEEN #{startDate} AND #{endDate}")
     Integer selectCountBySubtypeAndDateRange(@Param("subtype") String subtype, @Param("startDate") LocalDate startDate, @Param("endDate") LocalDate endDate);
+
     @Select("SELECT COUNT(1) FROM epiflu WHERE subtype = #{subtype} AND collection_date BETWEEN #{startDate} AND #{endDate} AND location LIKE CONCAT('%', #{continent}, '%')")
     Integer selectCountBySubtypeAndDateRangeWithContinent(@Param("subtype") String subtype, @Param("startDate") LocalDate SeasonStartDate, @Param("endDate") LocalDate SeasonEndDate, @Param("continent") String continent);
 
+//    @Select("<script>" +
+//            "SELECT DISTINCT clade " +
+//            "FROM epiflu " +
+//            "WHERE subtype = #{subtype} " +
+//            "AND is_china = #{isChina} " +
+//            "AND collection_date BETWEEN #{startDate} AND #{endDate} " +
+//            "<if test='constellation != null and constellation.size() > 0'>" +
+//            "</script>")
+//    List<String> findDistinctCladeBySearchWithConditions(@Param("subtype") String subtype, @Param("isChina") Integer isChina, @Param("startDate") LocalDate startDate, @Param("endDate") LocalDate endDate);
+
     /**
      * 查询指定洲的clade分布
      * @param continent 洲名称
@@ -42,4 +55,21 @@ public interface EpifluMapper extends BaseMapper<Epiflu> {
             "GROUP BY clade " +
             "ORDER BY count DESC")
     List<CladeCountResult> selectCladeCountByContinent(@Param("continent") String continent , @Param("subtype") String subType);
+
+    /**
+     * 查询指定日期、子类型和星座的记录数
+     * @param subtype 子类型
+     * @param constellation 星座
+     * @param date 日期
+     * @return 记录数
+     */
+    @Select("SELECT COUNT(*) FROM epiflu WHERE subtype = #{subtype} AND clade = #{constellation} AND collection_date = #{date}")
+    Integer selectDayCount(@Param("subtype") String subtype, @Param("constellation") String constellation, @Param("date") LocalDate date);
+
+    @Select("SELECT DISTINCT subtype FROM epiflu WHERE subtype = #{is_china}")
+    List<String> findDistinctSubtypeChina();
+
+    @Select("SELECT COUNT(*) FROM epiflu WHERE subtype = #{subtype} AND is_china = #{is_china} AND collection_date = #{startDate}")
+    Integer selectCount(@Param("subtype") String subtype, @Param("is_china") Integer is_china, @Param("startDate") LocalDate startDate);
+
 }

+ 35 - 0
src/main/java/com/qizhen/healsphere/repository/mapper/EpifluQueryMapper.java

@@ -0,0 +1,35 @@
+package com.qizhen.healsphere.repository.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qizhen.healsphere.web.param.Epiflu;
+import com.qizhen.healsphere.web.vo.InputVO;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+@Mapper
+public interface EpifluQueryMapper extends BaseMapper<Epiflu> {
+
+    /**
+     * 获取条件查询的条数
+     * @param inputVO 查询参数
+     * @return 符合条件的记录数
+     */
+    @Select("<script>" +
+            "SELECT COUNT(1) FROM epiflu " +
+            "WHERE 1=1 " +
+            "<if test='inputVO.subtype != null and inputVO.subtype.trim() != \"\"'> " +
+            "AND subtype = #{inputVO.subtype} " +
+            "</if>" +
+            "<if test='inputVO.constellation != null and !inputVO.constellation.isEmpty()'> " +
+            "AND clade IN " +
+            "<foreach item='item' collection='inputVO.constellation' open='(' separator=',' close=')'> " +
+            "#{item} " +
+            "</foreach> " +
+            "</if>" +
+            "<if test='inputVO.startDate != null and inputVO.endDate != null'> " +
+            "AND collection_date BETWEEN #{inputVO.startDate} AND #{inputVO.endDate} " +
+            "</if>" +
+            "</script>")
+    int getCountByQuery(@Param("inputVO") InputVO inputVO);
+}

+ 102 - 6
src/main/java/com/qizhen/healsphere/service/impl/ZYApiServiceImpl.java

@@ -3,13 +3,14 @@ package com.qizhen.healsphere.service.impl;
 import com.qizhen.healsphere.repository.mapper.BacteriaGenusMapper;
 import com.qizhen.healsphere.repository.mapper.EpifluMapper;
 import com.qizhen.healsphere.repository.mapper.StrainMapper;
+import com.qizhen.healsphere.repository.mapper.EpifluQueryMapper;
 import com.qizhen.healsphere.web.param.*;
+import com.qizhen.healsphere.web.vo.InputVO;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.time.LocalDate;
-import java.time.Year;
 import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
@@ -28,6 +29,9 @@ public class ZYApiServiceImpl {
     @Autowired
     private EpifluMapper epifluMapper;
 
+    @Autowired
+    private EpifluQueryMapper epifluQueryMapper;
+
     public List<BacteriaGenus> getBacteriaInfo(String input) {
         log.info("Calling getBacteriaInfo with input: {}", input);
         // 将输入字符串按逗号分割成列表
@@ -63,7 +67,7 @@ public class ZYApiServiceImpl {
         return epifluMapper.selectCountBySubtype(subType);
     }
 
-    public Map<String,Double> getCumulativeList(String subtype) {
+    public Map<String,Integer> getCumulativeList(String subtype) {
         Date maxCollectionDate = epifluMapper.findMaxCollectionDateBySubtype(subtype);
         // 更安全的日期转换方式
         LocalDate startDate = maxCollectionDate.toInstant()
@@ -73,7 +77,7 @@ public class ZYApiServiceImpl {
         LocalDate endDate = startDate.plusMonths(12).minusDays(1);
         DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
 
-        Map<String, Double> cumulative = new TreeMap<>(); // 使用 TreeMap 保持键的有序性
+        Map<String, Integer> cumulative = new TreeMap<>(); // 使用 TreeMap 保持键的有序性
         for (int i = 0; i < 12; i++) {
             LocalDate monthStartDate = startDate.plusMonths(i);
             LocalDate monthEndDate = monthStartDate.plusMonths(1).minusDays(1);
@@ -81,11 +85,27 @@ public class ZYApiServiceImpl {
             //如果要把逻辑改成每个月占比,把下面的 startDate改成monthStartDate
             int countInMonth = epifluMapper.selectCountBySubtypeAndDateRange(subtype, startDate, monthEndDate);
             int countInYear = epifluMapper.selectCountBySubtypeAndDateRange(subtype, startDate, endDate);
-            double percentage = (double) countInMonth / countInYear * 100;
-            cumulative.put(monthKey, Math.round(percentage * 10.0) / 10.0); // 保留小数点后一位
+            int percentage = (int) countInMonth / countInYear * 100;
+            cumulative.put(monthKey, (int) (Math.ceil(percentage * 10.0) / 10.0));
         }
         return cumulative;
     }
+    public Map<String, Integer> getCumulativeCountList(InputVO inputVO) {
+        LocalDate today = LocalDate.now();
+        LocalDate oneWeekAgo = today.minusWeeks(1);
+        Map<String, Integer> cumulative = new TreeMap<>();
+
+        // 遍历从 oneWeekAgo 到 today 的每一天
+        for (LocalDate date = oneWeekAgo; !date.isAfter(today); date = date.plusDays(1)) {
+            // 调用 mapper.selectCount 方法获取数量
+            Integer count = epifluMapper.selectCount(inputVO.getSubtype(), inputVO.getIsChina(), date);
+            // 将日期格式化为 yyyy-MM-dd 并存入 Map
+            cumulative.put(date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")), count);
+        }
+
+        return cumulative;
+    }
+
 //    public Map<String, Integer> getInEachContinentMap(String subtype) {
 //        List<String> continentList = Arrays.asList("Asia", "Europe", "Africa", "North America", "South America", "Oceania");
 //        Date maxCollectionDate = epifluMapper.findMaxCollectionDateBySubtype(subtype);
@@ -208,11 +228,87 @@ public Map<String, Object> getInEachContinentMap(String subtype) {
 
             geoInfoList.add(geoInfo);
         }
-
         return geoInfoList;
     }
+    public List<GeoInfo> getChineseGeoInfoList(InputVO inputVO){
+        return null;
+    }
+
     //获取所有的subType值
     public List<String> findDistinctSubtype(){
         return epifluMapper.findDistinctSubtype();
     }
+//
+//    public List<String> getCladeListBySearch(InputVO inputVO) {
+//        return epifluMapper.findDistinctCladeBySearchWithConditions(inputVO.getSubType(), 0, inputVO.getStartDate(), inputVO.getEndDate());
+//    }
+    public GraphInfo getGraphData(InputVO inputVO) {
+        GraphInfo graphInfo = new GraphInfo();
+
+        String subType = inputVO.getSubtype();
+        graphInfo.setEpifluentName("甲流"); // 写死
+        graphInfo.setClade(inputVO.getConstellation());
+        graphInfo.setSubtype(subType);
+
+        // 设置统计数据
+        graphInfo.setCount(epifluQueryMapper.getCountByQuery(inputVO));
+
+        // 获取 startDate 和 endDate
+        Date startDate = inputVO.getStartDate();
+        Date endDate = inputVO.getEndDate();
+
+        if (startDate != null && endDate != null) {
+            LocalDate startLocalDate = startDate.toInstant()
+                    .atZone(ZoneId.systemDefault())
+                    .toLocalDate();
+            LocalDate endLocalDate = endDate.toInstant()
+                    .atZone(ZoneId.systemDefault())
+                    .toLocalDate();
+            Map<String, Integer> dailyCounts = new TreeMap<>();
+            // 遍历 startDate 到 endDate 的每一天
+            for (LocalDate date = startLocalDate; !date.isAfter(endLocalDate); date = date.plusDays(1)) {
+                // 遍历 constellation 列表
+                int totalCount = 0;
+                for (String constellation : inputVO.getConstellation()) {
+                    Integer count = epifluMapper.selectDayCount(inputVO.getSubtype(), constellation, date);
+                    if (count != null) {
+                        totalCount += count;
+                    }
+                }
+                dailyCounts.put(date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")), totalCount);
+            }
+            // 设置累积数据
+            graphInfo.setCumulative(dailyCounts);
+        }
+        //TODO 总结分析
+
+        // 设置地理信息
+        graphInfo.setGeoInfoList(getGeoInfoList(subType));
+
+        return graphInfo;
+    }
+
+//    public int getQueryCount(InputVO inputVO) {
+//        return epifluQueryMapper.getCountByQuery(inputVO);
+//    }
+//
+//
+//    public Map<String,Double> getCumulativeListByInputVO(InputVO inputVO) {
+//        Date startDate = inputVO.getStartDate();
+//        Date endDate= inputVO.getEndDate();
+//
+//
+//        Map<String, Double> cumulative = new TreeMap<>(); // 使用 TreeMap 保持键的有序性
+//        for (int i = 0; i < 12; i++) {
+//            LocalDate monthStartDate = startDate.plusMonths(i);
+//            LocalDate monthEndDate = monthStartDate.plusMonths(1).minusDays(1);
+//            String monthKey = monthStartDate.format(formatter);
+//            //如果要把逻辑改成每个月占比,把下面的 startDate改成monthStartDate
+//            int countInMonth = epifluMapper.selectCountBySubtypeAndDateRange(subtype, startDate, monthEndDate);
+//            int countInYear = epifluMapper.selectCountBySubtypeAndDateRange(subtype, startDate, endDate);
+//            double percentage = (double) countInMonth / countInYear * 100;
+//            cumulative.put(monthKey, Math.round(percentage * 10.0) / 10.0); // 保留小数点后一位
+//        }
+//        return cumulative;
+//    }
 }

+ 57 - 16
src/main/java/com/qizhen/healsphere/web/ZYController.java

@@ -4,12 +4,14 @@ import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.qizhen.healsphere.ExplainAssistant;
+import com.qizhen.healsphere.repository.mapper.EpifluChineseQueryMapper;
 import com.qizhen.healsphere.service.impl.DepartmentServiceImpl;
 import com.qizhen.healsphere.service.impl.ZYApiServiceImpl;
 import com.qizhen.healsphere.web.param.BacteriaGenus;
 import com.qizhen.healsphere.web.param.DetailInfo;
 import com.qizhen.healsphere.web.param.GeoInfo;
 import com.qizhen.healsphere.web.param.GraphInfo;
+import com.qizhen.healsphere.web.vo.InputVO;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
@@ -44,6 +46,7 @@ public class ZYController {
 
         return detailInfo;
     }
+
     /**
      * 获取解释信息并清洗
      *
@@ -130,23 +133,61 @@ public class ZYController {
         }
         return cleanedList;
     }
-    @PostMapping("/graph")
+
+    @PostMapping("/international")
     @ResponseBody
-    public List<GraphInfo> getGraphInfo() {
-        List<GraphInfo> graphInfoList = new ArrayList<>();
-        List<String> subTypeList = zyApiService.findDistinctSubtype();
-        for (String subType : subTypeList) {
-            GraphInfo graphInfo = new GraphInfo();
-            graphInfo.setClade(zyApiService.getCladeList(subType));
-            graphInfo.setSubtype(subType);
-            graphInfo.setCount(zyApiService.getCount(subType));
-            graphInfo.setCumulative(zyApiService.getCumulativeList(subType));
-            graphInfo.setInEachContinent(zyApiService.getInEachContinentMap(subType));
-            graphInfo.setGeoInfoList(zyApiService.getGeoInfoList(subType));
-            graphInfoList.add(graphInfo);
+    public List<GraphInfo> getGraphInfo(@RequestBody(required = false) InputVO inputVO) {
+        if (inputVO == null) {
+            List<GraphInfo> graphInfoList = new ArrayList<>();
+            List<String> subTypeList = zyApiService.findDistinctSubtype();
+            for (String subType : subTypeList) {
+                GraphInfo graphInfo = new GraphInfo();
+                graphInfo.setEpifluentName("甲流");
+                graphInfo.setClade(zyApiService.getCladeList(subType));
+                graphInfo.setSubtype(subType);
+                graphInfo.setCount(zyApiService.getCount(subType));
+                graphInfo.setCumulative(zyApiService.getCumulativeList(subType));
+                //graphInfo.setInEachContinent(zyApiService.getInEachContinentMap(subType));
+                graphInfo.setGeoInfoList(zyApiService.getGeoInfoList(subType));
+                graphInfoList.add(graphInfo);
+            }
+            return graphInfoList;
         }
-        return graphInfoList;
-    }
 
+        GraphInfo graphData = zyApiService.getGraphData(inputVO);
+        List<GraphInfo> graphDataList = new ArrayList<>();
+        graphDataList.add(graphData);
+        return graphDataList;
 
-}
+    }
+//    @PostMapping("/international")
+//    @ResponseBody
+//    public List<GraphInfo> getInternalGraphInfo(@RequestBody InputVO inputVO) {
+//        List<GraphInfo> graphInfoList = new ArrayList<>();
+//            GraphInfo graphInfo = new GraphInfo();
+//            graphInfo.setClade(zyApiService.getCladeListBySearch(inputVO));
+////            graphInfo.setSubtype(inputVO);
+////            graphInfo.setCount(zyApiService.getCount(inputVO));
+////            graphInfo.setCumulative(zyApiService.getCumulativeList(inputVO));
+////            graphInfo.setInEachContinent(zyApiService.getInEachContinentMap(inputVO));
+////            graphInfo.setGeoInfoList(zyApiService.getGeoInfoList(inputVO));
+////            graphInfoList.add(graphInfo);
+//        return graphInfoList;
+//    }
+
+
+    @PostMapping("/Chinese")
+    @ResponseBody
+    public GraphInfo getChineseGraphInfo(@RequestBody(required = false) InputVO inputVO) {
+        //在此处编写方法
+//        GraphInfo graphInfo = new GraphInfo();
+//        graphInfo.setEpifluentName("甲流");
+//        graphInfo.setClade(inputVO.getConstellation());
+//        graphInfo.setSubtype(inputVO.getSubtype());
+//        graphInfo.setCount(epifluQueryMapper.getCountByQuery(inputVO));
+//        //graphInfo.setCumulative(zyApiService);
+//        return null;
+        GraphInfo graphData = zyApiService.getGraphData(inputVO);
+        return graphData;
+    }
+}

+ 14 - 0
src/main/java/com/qizhen/healsphere/web/param/ChineseGraphInfo.java

@@ -0,0 +1,14 @@
+package com.qizhen.healsphere.web.param;
+
+import java.util.List;
+import java.util.Map;
+
+public class ChineseGraphInfo {
+    private String epifluentName;
+    private List<String> clade;
+    private String subtype;
+    private int count;
+    private Map<String, Double> cumulative;
+    private List<GeoInfo> geoInfoList;
+    private String analyse;
+}

+ 5 - 3
src/main/java/com/qizhen/healsphere/web/param/GraphInfo.java

@@ -7,10 +7,12 @@ import java.util.Map;
 
 @Data
 public class GraphInfo {
+    private String epifluentName;
     private List<String> clade;
     private String subtype;
-    private int Count;
-    private Map<String, Double> cumulative;
-    private Map<String, Object> inEachContinent;
+    private int count;
+    private Map<String, Integer> cumulative;
+    //private Map<String, Object> inEachContinent;
+    private String analyse;
     private List<GeoInfo> geoInfoList;
 }

+ 8 - 1
src/main/java/com/qizhen/healsphere/web/vo/InputVO.java

@@ -1,8 +1,15 @@
 package com.qizhen.healsphere.web.vo;
 
 import lombok.Data;
+import java.time.LocalDate;
+import java.util.Date;
+import java.util.List;
 
 @Data
 public class InputVO {
-    private String text;
+    private List<String> constellation;
+    private String subtype;
+    private Integer isChina; // 0: 全球 1: 中国
+    private Date startDate;
+    private Date endDate;
 }