实现区级指标、小班属性和媒体接口

This commit is contained in:
2025-11-27 16:13:40 +08:00
parent 264236c74a
commit ffcadd7818
14 changed files with 542 additions and 210 deletions

View File

@@ -2,9 +2,11 @@ package com.whu.edu.LyStatistic.MapLyStatistic.Controller;
import com.whu.edu.LyStatistic.MapLyStatistic.Dto.DistrictStatsDTO; import com.whu.edu.LyStatistic.MapLyStatistic.Dto.DistrictStatsDTO;
import com.whu.edu.LyStatistic.MapLyStatistic.Dto.StreetStatsDTO; import com.whu.edu.LyStatistic.MapLyStatistic.Dto.StreetStatsDTO;
import com.whu.edu.LyStatistic.MapLyStatistic.Dto.PlotAttrDTO;
import com.whu.edu.LyStatistic.MapLyStatistic.Dto.PlotStatsDTO; import com.whu.edu.LyStatistic.MapLyStatistic.Dto.PlotStatsDTO;
import com.whu.edu.LyStatistic.MapLyStatistic.Dto.PlotBoundaryDTO; import com.whu.edu.LyStatistic.MapLyStatistic.Dto.PlotBoundaryDTO;
import com.whu.edu.LyStatistic.MapLyStatistic.Service.StatisticsService; import com.whu.edu.LyStatistic.MapLyStatistic.Service.StatisticsService;
import com.whu.edu.LyStatistic.MapLyStatistic.Service.PlotService;
import com.whu.edu.LyStatistic.Util.ApiResponse; import com.whu.edu.LyStatistic.Util.ApiResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@@ -22,6 +24,26 @@ public class StatisticsController {
@Autowired @Autowired
private StatisticsService statisticsService; private StatisticsService statisticsService;
@Autowired
private PlotService plotService;
/**
* 小班属性
* 入参内业小班号NYXBH+乡XIANG
*/
@GetMapping("/plot/attr")
public ApiResponse<PlotAttrDTO> getPlotAttr(@RequestParam String nyxbh, @RequestParam String xiang) {
try {
PlotAttrDTO data = plotService.getPlotAttributes(nyxbh, xiang);
return ApiResponse.success(data);
} catch (Exception e) {
return ApiResponse.error("查询小班属性失败:" + e.getMessage());
}
}
/** /**
* 区级统计 * 区级统计
@@ -29,19 +51,20 @@ public class StatisticsController {
@GetMapping("/district") @GetMapping("/district")
public ApiResponse<DistrictStatsDTO> getDistrictStats() { public ApiResponse<DistrictStatsDTO> getDistrictStats() {
try { try {
// 1⃣ 获取 Map<区名, PlotStatsDTO> // 1⃣ 获取各区统计 List
Map<String, PlotStatsDTO> statsMap = statisticsService.getAllDistrictStats(); List<PlotStatsDTO> statsList = statisticsService.getAllDistrictStats();
// 2⃣ 构建 DistrictStatsDTO // 2⃣ 构建 DTO 需要的 Map
Map<String, String> completionStatus = new LinkedHashMap<>(); Map<String, String> completionStatus = new LinkedHashMap<>();
Map<String, Double> plotArea = new LinkedHashMap<>(); Map<String, Double> plotArea = new LinkedHashMap<>();
Map<String, Integer> plotCount = new LinkedHashMap<>(); Map<String, Integer> plotCount = new LinkedHashMap<>();
for (Map.Entry<String, PlotStatsDTO> entry : statsMap.entrySet()) { for (PlotStatsDTO stats : statsList) {
String district = entry.getKey();
PlotStatsDTO stats = entry.getValue();
// 计算完成状态(示例逻辑,可根据需求调整) // stats.getDistrict() 需要在 DTO 里有 district 字段
String district = stats.getDistrict();
// 计算完成状态
String status; String status;
if (safeInt(stats.getApprovedCount()) > 0) { if (safeInt(stats.getApprovedCount()) > 0) {
status = "已完成"; status = "已完成";
@@ -59,70 +82,74 @@ public class StatisticsController {
DistrictStatsDTO dto = new DistrictStatsDTO(completionStatus, plotArea, plotCount); DistrictStatsDTO dto = new DistrictStatsDTO(completionStatus, plotArea, plotCount);
return ApiResponse.success(dto); return ApiResponse.success(dto);
} catch (Exception e) { } catch (Exception e) {
return ApiResponse.error("区级统计查询失败:" + e.getMessage()); return ApiResponse.error("区级统计查询失败:" + e.getMessage());
} }
} }
@GetMapping("/street")
public ApiResponse<StreetStatsDTO> getStreetStats(@RequestParam String district) {
try {
// 1⃣ 获取 Map<街道名, PlotStatsDTO>
Map<String, PlotStatsDTO> statsMap = statisticsService.getStreetStatsByDistrict(district);
// 2⃣ 构建统计 DTO // @GetMapping("/street")
Map<String, String> completionStatus = new LinkedHashMap<>(); // public ApiResponse<StreetStatsDTO> getStreetStats(@RequestParam String district) {
Map<String, Double> plotArea = new LinkedHashMap<>(); // try {
Map<String, Integer> plotCount = new LinkedHashMap<>(); // // 1⃣ 获取 Map<街道名, PlotStatsDTO>
// Map<String, PlotStatsDTO> statsMap = statisticsService.getStreetStatsByDistrict(district);
for (Map.Entry<String, PlotStatsDTO> entry : statsMap.entrySet()) { //
String street = entry.getKey(); // // 2⃣ 构建统计 DTO
PlotStatsDTO stats = entry.getValue(); // Map<String, String> completionStatus = new LinkedHashMap<>();
// Map<String, Double> plotArea = new LinkedHashMap<>();
// 判断状态(逻辑与区级相同) // Map<String, Integer> plotCount = new LinkedHashMap<>();
String status; //
if (safeInt(stats.getApprovedCount()) > 0) { // for (Map.Entry<String, PlotStatsDTO> entry : statsMap.entrySet()) {
status = "已完成"; // String street = entry.getKey();
} else if (safeInt(stats.getCollectedCount()) > 0) { // PlotStatsDTO stats = entry.getValue();
status = "未完成"; //
} else { // // 判断状态(逻辑与区级相同)
status = "未开始"; // String status;
} // if (safeInt(stats.getApprovedCount()) > 0) {
// status = "已完成";
completionStatus.put(street, status); // } else if (safeInt(stats.getCollectedCount()) > 0) {
plotArea.put(street, safeDouble(stats.getTotalArea())); // status = "未完成";
plotCount.put(street, safeInt(stats.getPlotCount())); // } else {
} // status = "未开始";
// }
StreetStatsDTO dto = new StreetStatsDTO(completionStatus, plotArea, plotCount); //
// completionStatus.put(street, status);
return ApiResponse.success(dto); // plotArea.put(street, safeDouble(stats.getTotalArea()));
// plotCount.put(street, safeInt(stats.getPlotCount()));
} catch (Exception e) { // }
return ApiResponse.error("街道统计查询失败:" + e.getMessage()); //
} // StreetStatsDTO dto = new StreetStatsDTO(completionStatus, plotArea, plotCount);
} //
// return ApiResponse.success(dto);
/** //
* ✅ 新增接口:一次性获取所有小班边界(无参) // } catch (Exception e) {
* URL: GET /api/stats/boundaries/all // return ApiResponse.error("街道统计查询失败:" + e.getMessage());
*/ // }
@GetMapping("/boundaries/all") // }
public ApiResponse<List<PlotBoundaryDTO>> getAllBoundaries() { //
try { // /**
long startTime = System.currentTimeMillis(); // * ✅ 新增接口:一次性获取所有小班边界(无参)
// * URL: GET /api/stats/boundaries/all
// 调用 Service 获取全量数据 // */
List<PlotBoundaryDTO> list = statisticsService.getAllBoundaries(); // @GetMapping("/boundaries/all")
// public ApiResponse<List<PlotBoundaryDTO>> getAllBoundaries() {
long duration = System.currentTimeMillis() - startTime; // try {
System.out.println("全量加载小班边界耗时: " + duration + "ms, 总数量: " + list.size()); // long startTime = System.currentTimeMillis();
//
return ApiResponse.success(list); // // 调用 Service 获取全量数据
} catch (Exception e) { // List<PlotBoundaryDTO> list = statisticsService.getAllBoundaries();
return ApiResponse.error("获取所有图斑边界失败:" + e.getMessage()); //
} // long duration = System.currentTimeMillis() - startTime;
} // System.out.println("全量加载小班边界耗时: " + duration + "ms, 总数量: " + list.size());
//
// return ApiResponse.success(list);
// } catch (Exception e) {
// return ApiResponse.error("获取所有图斑边界失败:" + e.getMessage());
// }
// }
//
//
// 防止 null // 防止 null

View File

@@ -0,0 +1,162 @@
package com.whu.edu.LyStatistic.MapLyStatistic.Dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PlotAttrDTO {
private String id;
private String databaseName;
private String taskName;
private String tableName;
private String collectorName;
private String bc0;
private String bc1;
private String bc2;
private String bc3;
private String bc4;
private String bcl;
private String bgDlbm;
private String bhdj;
private String bhlydj;
private String bz;
private String cbgd;
private String cun;
private String diLei;
private String diMao;
private String djmxjbdj;
private String dwhj;
private String dwzl;
private String fzzhd;
private String fzzhddm;
private String gcfq;
private String gclx;
private String gmgd;
private String gmgddj;
private String gmlgd;
private String grlx;
private String grqd;
private String haiBa;
private String hj;
private String hqjycslx;
private String huoLmXj;
private String jjlcq;
private String jjz;
private String jtqw;
private String jycslx;
private String kdmFblx;
private String kdmSl;
private String kjd;
private String kyqk;
private String kzlyhd;
private String kzlyhddm;
private String lcjg;
private String ldaiHj;
private String ldaiHs;
private String ldaiZj;
private String ldbhdj;
private String ldfljd;
private String ldlx;
private String ldshdj;
private String ldsyqsO;
private String ldsyqsU;
private String ldwsdj;
private String ldzldj;
private String lfccl;
private String lfccldj;
private String lfcclDj;
private String linChang;
private String linZhong;
private String lj;
private String ljz;
private String lmqs;
private String lmsyqs;
private String lmzl;
private String lmzldj;
private String lxjjzl;
private String lyzylb;
private String meiGqXj;
private String nyxbh;
private String pjmsg;
private String pjmxj;
private String pjnl;
private String pjSg;
private String pjXj;
private String poDu;
private String poDuDm;
private String poWei;
private String poXiang;
private String qiYuan;
private String qmlxj;
private String qqjycslx;
private String qqjycx;
private String qyxbh;
private String sheng;
private String shi;
private String sj;
private String slhldj;
private String sljkdj;
private String sllb;
private String sllyzy;
private String slqlgc;
private String slqljg;
private String slzhdj;
private String slzhlx;
private String spljydj;
private String spycsbl;
private String sqdj;
private String stqw;
private String szjg;
private String szzc;
private String tchd;
private String tchddm;
private String tdgllx;
private String trgxdj;
private String trlx;
private String trmc;
private String trzd;
private String wclZdfs;
private String wclZdgg;
private String xbh;
private String xbmj;
private String xbmjGq;
private String xbz;
private String xbzs;
private String xian;
private String xiang;
private String xiBh;
private String ybddj;
private String yds;
private String yssz;
private String yuBiDu;
private String zbfglx;
private String zbgd;
private String zbzgd;
private String zdkjlx;
private String zfsblx;
private String zhj;
private String zj;
private String zlnd;
private String zlwz;
private String zrd;
private String zynt;
private String collector;
private String collector0;
private String createTime;
private String reason;
private String reviewer;
private String reviewer0;
private String shape;
private String status;
private String updateTime;
private String updateTime0;
private String version;
private List<String> mediaPathList;
// 这里需要生成getter和setter方法
// 可以使用IDE自动生成或Lombok注解
}

View File

@@ -0,0 +1,14 @@
package com.whu.edu.LyStatistic.MapLyStatistic.Dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PlotImageDTO {
private String id;
private String databaseName;
}

View File

@@ -8,6 +8,7 @@ import lombok.NoArgsConstructor;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class PlotStatsDTO { public class PlotStatsDTO {
private String district;
private Integer plotCount; // 图斑总数量 private Integer plotCount; // 图斑总数量
private Double totalArea; // 图斑总面积sum XBMJ private Double totalArea; // 图斑总面积sum XBMJ

View File

@@ -4,9 +4,8 @@ import lombok.Data;
@Data @Data
public class UnitInfo { public class UnitInfo {
private String taskName; // private String taskName;
private String schemaCode; // private String unitName;
private String unitName;
private String district; private String district;
private String village; private String village;
} }

View File

@@ -0,0 +1,15 @@
package com.whu.edu.LyStatistic.MapLyStatistic.Mapper;
import com.whu.edu.LyStatistic.MapLyStatistic.Dto.PlotAttrDTO;
import com.whu.edu.LyStatistic.MapLyStatistic.Dto.UnitInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface PlotMapper {
PlotAttrDTO findPlotAttributes(@Param("nyxbh") String nyxbh,@Param("xiang") String xiang);
List<String> findMediaPaths(@Param("id") String id,
@Param("databaseName") String databaseName);
}

View File

@@ -21,6 +21,11 @@ public interface TaskCommonMapper {
* @return 统计结果 DTO * @return 统计结果 DTO
*/ */
PlotStatsDTO selectPlotStats(@Param("schema") String schema); PlotStatsDTO selectPlotStats(@Param("schema") String schema);
/**
* 按照区统计图斑信息(数量、面积、各状态)
* @return 统计结果 DTO
*/
List<PlotStatsDTO> selectPlotStatsByDistrict();
/** /**
* 获取所有小班的ID和边界信息 * 获取所有小班的ID和边界信息
* * @param schema 动态传入的数据库模式名 * * @param schema 动态传入的数据库模式名

View File

@@ -21,13 +21,13 @@ public class BaseTaskQueryService {
PlotStatsDTO stats = taskCommonMapper.selectPlotStats(schema); PlotStatsDTO stats = taskCommonMapper.selectPlotStats(schema);
if (stats == null) { if (stats == null) {
// 防止 mapper 返回 null // 防止 mapper 返回 null
return new PlotStatsDTO(0, 0.0, 0, 0, 0, 0); return new PlotStatsDTO( "0", 0, 0.0, 0, 0, 0, 0);
} }
return stats; return stats;
} catch (Exception e) { } catch (Exception e) {
// 表不存在或 schema 不存在,直接跳过 // 表不存在或 schema 不存在,直接跳过
// 不管是什么异常,都返回默认统计,保证批量统计不被中断 // 不管是什么异常,都返回默认统计,保证批量统计不被中断
return new PlotStatsDTO(0, 0.0, 0, 0, 0, 0); return new PlotStatsDTO( "0", 00, 0.0, 0, 0, 0, 0);
} }
} }

View File

@@ -0,0 +1,33 @@
package com.whu.edu.LyStatistic.MapLyStatistic.Service;
import com.whu.edu.LyStatistic.MapLyStatistic.Dto.PlotAttrDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.whu.edu.LyStatistic.MapLyStatistic.Mapper.PlotMapper;
import java.util.List;
@Service
public class PlotService {
@Autowired
private PlotMapper plotMapper; // 查询 unit_info 表
/**
* 查询小班属性
* 条件NYXBH + XIANG
*/
public PlotAttrDTO getPlotAttributes(String nyxbh, String xiang){
// ① 通过 NYXBH + XIANG
PlotAttrDTO schema = plotMapper.findPlotAttributes(nyxbh, xiang);
if (schema == null) {
throw new RuntimeException("未找到对应的小班所在任务 schema");
}
// 第二次查 media_path 列表
List<String> mediaPaths = plotMapper.findMediaPaths(schema.getId(), schema.getDatabaseName());
// 设置到 DTO 中
schema.setMediaPathList(mediaPaths);
return schema;
}
}

View File

@@ -1,5 +1,6 @@
package com.whu.edu.LyStatistic.MapLyStatistic.Service; package com.whu.edu.LyStatistic.MapLyStatistic.Service;
import com.whu.edu.LyStatistic.MapLyStatistic.Dto.PlotStatsDTO; import com.whu.edu.LyStatistic.MapLyStatistic.Dto.PlotStatsDTO;
import com.whu.edu.LyStatistic.MapLyStatistic.Dto.PlotAttrDTO;
import com.whu.edu.LyStatistic.MapLyStatistic.Dto.PlotBoundaryDTO; import com.whu.edu.LyStatistic.MapLyStatistic.Dto.PlotBoundaryDTO;
import com.whu.edu.LyStatistic.MapLyStatistic.Dto.UnitInfo; import com.whu.edu.LyStatistic.MapLyStatistic.Dto.UnitInfo;
import com.whu.edu.LyStatistic.MapLyStatistic.Mapper.InfoMapper; import com.whu.edu.LyStatistic.MapLyStatistic.Mapper.InfoMapper;
@@ -8,10 +9,7 @@ import com.whu.edu.LyStatistic.MapLyStatistic.Service.BaseService.BaseTaskQueryS
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.*;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Service @Service
@@ -23,70 +21,74 @@ public class StatisticsService {
private BaseTaskQueryService baseQueryService; // 通用任务查询 Service private BaseTaskQueryService baseQueryService; // 通用任务查询 Service
@Autowired @Autowired
private TaskCommonMapper taskCommonMapper; private TaskCommonMapper taskCommonMapper;
/** /**
* 查询单个区的统计信息 * 查询单个区的统计信息
*/ */
public PlotStatsDTO getDistrictStats(String district) { // public PlotStatsDTO getDistrictStats(String district) {
//
// 1. 获取该区所有任务schema // // 1. 获取该区所有任务schema
List<UnitInfo> tasks = unitInfoMapper.findByDistrict(district); // List<UnitInfo> tasks = unitInfoMapper.findByDistrict(district);
//
// 2. 初始化统计对象 // // 2. 初始化统计对象
PlotStatsDTO total = new PlotStatsDTO(0, 0.0, 0, 0, 0, 0); // PlotStatsDTO total = new PlotStatsDTO(0, 0.0, 0, 0, 0, 0);
//
// 3. 遍历每个任务 schema累加统计 // // 3. 遍历每个任务 schema累加统计
for (UnitInfo task : tasks) { // for (UnitInfo task : tasks) {
String schema = task.getSchemaCode(); // String schema = task.getSchemaCode();
PlotStatsDTO stats = baseQueryService.queryPlotStats(schema); // PlotStatsDTO stats = baseQueryService.queryPlotStats(schema);
merge(total, stats); // merge(total, stats);
} // }
//
return total; // return total;
} // }
/** /**
* 查询所有区的统计信息 * 查询所有区的统计信息
* 返回 Map<区名, PlotStatsDTO> * 返回 Map<区名, PlotStatsDTO>
*/ */
public Map<String, PlotStatsDTO> getAllDistrictStats() { public List<PlotStatsDTO> getAllDistrictStats() {
//
// // 1⃣ 查询 unit_info 全部数据
// List<UnitInfo> allTasks = unitInfoMapper.findAll();
//
// // 2⃣ 按 district 分组
// Map<String, List<UnitInfo>> grouped =
// allTasks.stream().collect(Collectors.groupingBy(UnitInfo::getDistrict));
//
// Map<String, PlotStatsDTO> result = new LinkedHashMap<>();
//
// // 3⃣ 遍历每个区,累加统计
// for (Map.Entry<String, List<UnitInfo>> entry : grouped.entrySet()) {
//
// String district = entry.getKey();
// List<UnitInfo> tasks = entry.getValue();
//
// // 初始化累加对象
// PlotStatsDTO total = new PlotStatsDTO(0, 0.0, 0, 0, 0, 0);
//
// for (UnitInfo task : tasks) {
// PlotStatsDTO stats = taskCommonMapper.selectPlotStatsByDistrict(); // ✅ 使用安全方法
//
// if (stats != null) {
// // 累加
// total.setPlotCount(total.getPlotCount() + safeInt(stats.getPlotCount()));
// total.setTotalArea(total.getTotalArea() + safeDouble(stats.getTotalArea()));
// total.setUnPassedCount(total.getUnPassedCount() + safeInt(stats.getUnPassedCount()));
// total.setAssignedCount(total.getAssignedCount() + safeInt(stats.getAssignedCount()));
// total.setCollectedCount(total.getCollectedCount() + safeInt(stats.getCollectedCount()));
// total.setApprovedCount(total.getApprovedCount() + safeInt(stats.getApprovedCount()));
// }
// }
//
// result.put(district, total);
// }
//
// return result;
// 直接从数据库一次性查出“按区聚合后的统计数据”
List<PlotStatsDTO> list = taskCommonMapper.selectPlotStatsByDistrict();
// 1⃣ 查询 unit_info 全部数据 return list;
List<UnitInfo> allTasks = unitInfoMapper.findAll();
// 2⃣ 按 district 分组
Map<String, List<UnitInfo>> grouped =
allTasks.stream().collect(Collectors.groupingBy(UnitInfo::getDistrict));
Map<String, PlotStatsDTO> result = new LinkedHashMap<>();
// 3⃣ 遍历每个区,累加统计
for (Map.Entry<String, List<UnitInfo>> entry : grouped.entrySet()) {
String district = entry.getKey();
List<UnitInfo> tasks = entry.getValue();
// 初始化累加对象
PlotStatsDTO total = new PlotStatsDTO(0, 0.0, 0, 0, 0, 0);
for (UnitInfo task : tasks) {
String schema = task.getSchemaCode();
PlotStatsDTO stats = baseQueryService.queryPlotStats(schema); // ✅ 使用安全方法
if (stats != null) {
// 累加
total.setPlotCount(total.getPlotCount() + safeInt(stats.getPlotCount()));
total.setTotalArea(total.getTotalArea() + safeDouble(stats.getTotalArea()));
total.setUnPassedCount(total.getUnPassedCount() + safeInt(stats.getUnPassedCount()));
total.setAssignedCount(total.getAssignedCount() + safeInt(stats.getAssignedCount()));
total.setCollectedCount(total.getCollectedCount() + safeInt(stats.getCollectedCount()));
total.setApprovedCount(total.getApprovedCount() + safeInt(stats.getApprovedCount()));
}
}
result.put(district, total);
}
return result;
} }
@@ -94,77 +96,77 @@ public class StatisticsService {
* 按街道统计(传入区名称) * 按街道统计(传入区名称)
* 返回 Map<街道名, PlotStatsDTO> * 返回 Map<街道名, PlotStatsDTO>
*/ */
public Map<String, PlotStatsDTO> getStreetStatsByDistrict(String district) { // public Map<String, PlotStatsDTO> getStreetStatsByDistrict(String district) {
//
// 1⃣ 获取该区所有任务 // // 1⃣ 获取该区所有任务
List<UnitInfo> tasksInDistrict = unitInfoMapper.findByDistrict(district); // List<UnitInfo> tasksInDistrict = unitInfoMapper.findByDistrict(district);
//
// 防止该区没有数据 // // 防止该区没有数据
if (tasksInDistrict == null || tasksInDistrict.isEmpty()) { // if (tasksInDistrict == null || tasksInDistrict.isEmpty()) {
return new LinkedHashMap<>(); // return new LinkedHashMap<>();
} // }
//
// 2⃣ 按街道分组 // // 2⃣ 按街道分组
Map<String, List<UnitInfo>> groupedByStreet = // Map<String, List<UnitInfo>> groupedByStreet =
tasksInDistrict.stream().collect(Collectors.groupingBy(UnitInfo::getVillage)); // tasksInDistrict.stream().collect(Collectors.groupingBy(UnitInfo::getVillage));
//
Map<String, PlotStatsDTO> result = new LinkedHashMap<>(); // Map<String, PlotStatsDTO> result = new LinkedHashMap<>();
//
// 3⃣ 遍历每个街道,累加统计 // // 3⃣ 遍历每个街道,累加统计
for (Map.Entry<String, List<UnitInfo>> entry : groupedByStreet.entrySet()) { // for (Map.Entry<String, List<UnitInfo>> entry : groupedByStreet.entrySet()) {
//
String street = entry.getKey(); // String street = entry.getKey();
List<UnitInfo> streetTasks = entry.getValue(); // List<UnitInfo> streetTasks = entry.getValue();
//
// 初始化统计对象 // // 初始化统计对象
PlotStatsDTO total = new PlotStatsDTO(0, 0.0, 0, 0, 0, 0); // PlotStatsDTO total = new PlotStatsDTO(0, 0.0, 0, 0, 0, 0);
//
// 遍历该街道的所有 schema // // 遍历该街道的所有 schema
for (UnitInfo task : streetTasks) { // for (UnitInfo task : streetTasks) {
String schema = task.getSchemaCode(); // String schema = task.getSchemaCode();
PlotStatsDTO stats = baseQueryService.queryPlotStats(schema); // PlotStatsDTO stats = baseQueryService.queryPlotStats(schema);
//
if (stats != null) { // if (stats != null) {
total.setPlotCount(total.getPlotCount() + safeInt(stats.getPlotCount())); // total.setPlotCount(total.getPlotCount() + safeInt(stats.getPlotCount()));
total.setTotalArea(total.getTotalArea() + safeDouble(stats.getTotalArea())); // total.setTotalArea(total.getTotalArea() + safeDouble(stats.getTotalArea()));
total.setUnPassedCount(total.getUnPassedCount() + safeInt(stats.getUnPassedCount())); // total.setUnPassedCount(total.getUnPassedCount() + safeInt(stats.getUnPassedCount()));
total.setAssignedCount(total.getAssignedCount() + safeInt(stats.getAssignedCount())); // total.setAssignedCount(total.getAssignedCount() + safeInt(stats.getAssignedCount()));
total.setCollectedCount(total.getCollectedCount() + safeInt(stats.getCollectedCount())); // total.setCollectedCount(total.getCollectedCount() + safeInt(stats.getCollectedCount()));
total.setApprovedCount(total.getApprovedCount() + safeInt(stats.getApprovedCount())); // total.setApprovedCount(total.getApprovedCount() + safeInt(stats.getApprovedCount()));
} // }
} // }
//
// 添加到结果 Map // // 添加到结果 Map
result.put(street, total); // result.put(street, total);
} // }
//
return result; // return result;
} // }
//
public List<PlotBoundaryDTO> getAllBoundaries() { // public List<PlotBoundaryDTO> getAllBoundaries() {
List<PlotBoundaryDTO> totalBoundaries = new ArrayList<>(); // List<PlotBoundaryDTO> totalBoundaries = new ArrayList<>();
//
// 1. 查询所有任务信息 (UnitInfo) // // 1. 查询所有任务信息 (UnitInfo)
List<UnitInfo> allTasks = unitInfoMapper.findAll(); // List<UnitInfo> allTasks = unitInfoMapper.findAll();
//
// 2. 遍历每个任务,查询对应的表 // // 2. 遍历每个任务,查询对应的表
for (UnitInfo task : allTasks) { // for (UnitInfo task : allTasks) {
String schema = task.getSchemaCode(); // String schema = task.getSchemaCode();
try { // try {
// 调用 Mapper 查询该 schema 下的小班 // // 调用 Mapper 查询该 schema 下的小班
List<PlotBoundaryDTO> boundaries = taskCommonMapper.selectAllPlotBoundaries(schema); // List<PlotBoundaryDTO> boundaries = taskCommonMapper.selectAllPlotBoundaries(schema);
//
if (boundaries != null && !boundaries.isEmpty()) { // if (boundaries != null && !boundaries.isEmpty()) {
totalBoundaries.addAll(boundaries); // totalBoundaries.addAll(boundaries);
} // }
} catch (Exception e) { // } catch (Exception e) {
// 捕获异常(例如某个表不存在),打印日志但不中断整个流程 // // 捕获异常(例如某个表不存在),打印日志但不中断整个流程
System.err.println("查询 schema 失败: " + schema + ", 错误: " + e.getMessage()); // System.err.println("查询 schema 失败: " + schema + ", 错误: " + e.getMessage());
} // }
} // }
//
return totalBoundaries; // return totalBoundaries;
} // }
// ✅ 防止 null 值累加 // ✅ 防止 null 值累加

View File

@@ -4,7 +4,7 @@ server.port=9001
server.address=0.0.0.0 server.address=0.0.0.0
spring.datasource.host=120.48.89.193 spring.datasource.host=120.48.89.193
spring.datasource.port=5432 spring.datasource.port=5432
spring.datasource.database=lydc_statistic spring.datasource.database=linye_statistic
spring.datasource.driver-class-name=org.postgresql.Driver spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://${spring.datasource.host}:${spring.datasource.port}/${spring.datasource.database}?useSSL=true&allowMultiQueries=true spring.datasource.url=jdbc:postgresql://${spring.datasource.host}:${spring.datasource.port}/${spring.datasource.database}?useSSL=true&allowMultiQueries=true
spring.datasource.username=postgres spring.datasource.username=postgres

View File

@@ -6,20 +6,26 @@
<mapper namespace="com.whu.edu.LyStatistic.MapLyStatistic.Mapper.InfoMapper"> <mapper namespace="com.whu.edu.LyStatistic.MapLyStatistic.Mapper.InfoMapper">
<select id="findByDistrict" resultType="com.whu.edu.LyStatistic.MapLyStatistic.Dto.UnitInfo"> <select id="findByDistrict" resultType="com.whu.edu.LyStatistic.MapLyStatistic.Dto.UnitInfo">
SELECT task_name, schema_code, unit_name, district, village SELECT task_name, unit_name, district, village
FROM public.unit_info FROM merged.roottable1_merged
WHERE district = #{district} WHERE district = #{district}
</select> </select>
<select id="findByVillage" resultType="com.whu.edu.LyStatistic.MapLyStatistic.Dto.UnitInfo"> <select id="findByVillage" resultType="com.whu.edu.LyStatistic.MapLyStatistic.Dto.UnitInfo">
SELECT task_name, schema_code, unit_name, district, village SELECT task_name,unit_name, district, village
FROM public.unit_info FROM merged.roottable1_merged
WHERE village = #{village} WHERE village = #{village}
</select> </select>
<select id="findAll" resultType="com.whu.edu.LyStatistic.MapLyStatistic.Dto.UnitInfo"> <select id="findAll" resultType="com.whu.edu.LyStatistic.MapLyStatistic.Dto.UnitInfo">
SELECT task_name, schema_code, unit_name, district, village SELECT district, village
FROM public.unit_info FROM merged.roottable1_merged
</select> </select>
<select id="findAllRegion" resultType="com.whu.edu.LyStatistic.MapLyStatistic.Dto.UnitInfo">
SELECT region, regionid
FROM region
</select>
</mapper> </mapper>

View File

@@ -0,0 +1,24 @@
<?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.whu.edu.LyStatistic.MapLyStatistic.Mapper.PlotMapper">
<select id="findPlotAttributes" resultType="com.whu.edu.LyStatistic.MapLyStatistic.Dto.PlotAttrDTO">
SELECT *
FROM merged.roottable1_merged
WHERE "NYXBH" = #{nyxbh} AND "XIANG" = #{xiang}
LIMIT 1
</select>
<select id="findMediaPaths" resultType="string">
SELECT media_path
FROM merged.roottable1_media_merged
WHERE "id" = #{id}
AND "database_name" = #{databaseName}
ORDER BY media_path
</select>
</mapper>

View File

@@ -5,13 +5,56 @@
<mapper namespace="com.whu.edu.LyStatistic.MapLyStatistic.Mapper.TaskCommonMapper"> <mapper namespace="com.whu.edu.LyStatistic.MapLyStatistic.Mapper.TaskCommonMapper">
<!-- <!--按区
统计图斑信息: 统计图斑信息:
- plotCount: 图斑数量 - plotCount: 图斑数量
- totalArea: 图斑面积汇总 (XBMJ) - totalArea: 图斑面积汇总 (XBMJ)
- 各状态数量 (-1,0,1,2) - 各状态数量 (-1,0,1,2)
--> -->
<select id="selectPlotStats" resultType="com.whu.edu.LyStatistic.MapLyStatistic.Dto.PlotStatsDTO"> <!-- <select id="selectPlotStatsByDistrict" resultType="com.whu.edu.LyStatistic.MapLyStatistic.Dto.PlotStatsDTO">-->
<!-- SELECT-->
<!-- COUNT(*) AS plotCount,-->
<!-- COALESCE(SUM("XBMJ"), 0) AS totalArea,-->
<!-- COALESCE(SUM(CASE WHEN "status" = -1 THEN 1 ELSE 0 END), 0) AS unPassedCount,-->
<!-- COALESCE(SUM(CASE WHEN "status" = 0 THEN 1 ELSE 0 END), 0) AS assignedCount,-->
<!-- COALESCE(SUM(CASE WHEN "status" = 1 THEN 1 ELSE 0 END), 0) AS collectedCount,-->
<!-- COALESCE(SUM(CASE WHEN "status" = 2 THEN 1 ELSE 0 END), 0) AS approvedCount-->
<!-- FROM merged.roottable1_merged-->
<!-- WHERE district = #{district}-->
<!-- </select>-->
<select id="selectPlotStatsByDistrict"
resultType="com.whu.edu.LyStatistic.MapLyStatistic.Dto.PlotStatsDTO">
SELECT
r.region AS district,
-- 统计总行数plotCount
COUNT(*) AS plotCount,
-- 面积求和XBMJ 是 text需要转 numeric
COALESCE(SUM(NULLIF(m."XBMJ", '')::numeric), 0) AS totalArea,
-- status 也是 text因此必须先转 integer
COALESCE(SUM(CASE WHEN m."status"::int = -1 THEN 1 ELSE 0 END), 0) AS unPassedCount,
COALESCE(SUM(CASE WHEN m."status"::int = 0 THEN 1 ELSE 0 END), 0) AS assignedCount,
COALESCE(SUM(CASE WHEN m."status"::int = 1 THEN 1 ELSE 0 END), 0) AS collectedCount,
COALESCE(SUM(CASE WHEN m."status"::int = 2 THEN 1 ELSE 0 END), 0) AS approvedCount
FROM merged.roottable1_merged m
JOIN region r
ON substring(m."CUN", 1, 6) = r.regionid::text
GROUP BY r.region
ORDER BY r.region
</select>
<!--按街道
统计图斑信息:
- plotCount: 图斑数量
- totalArea: 图斑面积汇总 (XBMJ)
- 各状态数量 (-1,0,1,2)
-->
<select id="selectPlotStatsByStreet" resultType="com.whu.edu.LyStatistic.MapLyStatistic.Dto.PlotStatsDTO">
SELECT SELECT
COUNT(*) AS plotCount, COUNT(*) AS plotCount,
COALESCE(SUM("XBMJ"), 0) AS totalArea, COALESCE(SUM("XBMJ"), 0) AS totalArea,
@@ -19,7 +62,8 @@
COALESCE(SUM(CASE WHEN "status" = 0 THEN 1 ELSE 0 END), 0) AS assignedCount, COALESCE(SUM(CASE WHEN "status" = 0 THEN 1 ELSE 0 END), 0) AS assignedCount,
COALESCE(SUM(CASE WHEN "status" = 1 THEN 1 ELSE 0 END), 0) AS collectedCount, COALESCE(SUM(CASE WHEN "status" = 1 THEN 1 ELSE 0 END), 0) AS collectedCount,
COALESCE(SUM(CASE WHEN "status" = 2 THEN 1 ELSE 0 END), 0) AS approvedCount COALESCE(SUM(CASE WHEN "status" = 2 THEN 1 ELSE 0 END), 0) AS approvedCount
FROM "${schema}".roottable1 FROM merged.roottable1_merged
WHERE village = #{village}
</select> </select>