This commit is contained in:
moonlight557
2025-10-13 16:27:30 +08:00
parent 3bcf1b595c
commit ec7d0e09df
23 changed files with 620 additions and 146 deletions

View File

@@ -19,7 +19,7 @@ public class ApiResponse<T> {
}
public static <T> ApiResponse<T> success(String message, T data) {
return new ApiResponse<>(0, message, data);
return new ApiResponse<>(200, message, data);
}
public static <T> ApiResponse<T> error(int code, String message) {

View File

@@ -0,0 +1,28 @@
package com.whu.edu.LyStatistic.statistic.config;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class CorsConfig {
@Bean
public FilterRegistrationBean<CorsFilter> corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOriginPattern("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
config.setAllowCredentials(true); // 如果需要携带 Cookie
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
bean.setOrder(0); // 设置为最优先,优先于 Shiro
return bean;
}
}

View File

@@ -1,35 +0,0 @@
package com.whu.edu.LyStatistic.statistic.controller;
import com.whu.edu.LyStatistic.statistic.Util.ApiResponse;
import com.whu.edu.LyStatistic.statistic.dto.TaskStatisticResult;
import com.whu.edu.LyStatistic.statistic.service.OrgStatisticService;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.*;
@RestController
@RequestMapping("/api/org-statistics")
public class OrgStatisticController {
private final OrgStatisticService orgStatisticService;
public OrgStatisticController(OrgStatisticService orgStatisticService) {
this.orgStatisticService = orgStatisticService;
}
@GetMapping
public ApiResponse<Map<String, TaskStatisticResult>> getOrgStatistics(
@RequestParam String orgName,
@RequestParam(required = false)
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime time) {
List<String> tables = Arrays.asList("roottable1");
Map<String, TaskStatisticResult> result =
orgStatisticService.getOrgTaskStatistics(orgName, time, tables);
return ApiResponse.success(result);
}
}

View File

@@ -0,0 +1,86 @@
package com.whu.edu.LyStatistic.statistic.controller;
import com.whu.edu.LyStatistic.statistic.Util.ApiResponse;
import com.whu.edu.LyStatistic.statistic.dto.TaskStatisticResult;
import com.whu.edu.LyStatistic.statistic.service.*;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.*;
@RestController
@RequestMapping("/api")
public class StatisticController {
private final OrgStatisticService orgStatisticService;
private final DistrictStatisticService districtStatisticService;
private final UserStatisticService userStatisticService ;
private final UnitInfoService unitInfoService;
public StatisticController(OrgStatisticService orgStatisticService, DistrictStatisticService districtStatisticService,UserStatisticService userStatisticService,UnitInfoService unitInfoService) {
this.orgStatisticService = orgStatisticService;
this.districtStatisticService = districtStatisticService;
this.userStatisticService = userStatisticService;
this.unitInfoService = unitInfoService;
}
@GetMapping("/org-statistics")
public ApiResponse<Map<String, TaskStatisticResult>> getOrgStatistics(
@RequestParam String orgName,
@RequestParam(required = false)
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startTime,
@RequestParam(required = false)
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endTime) {
Map<String, TaskStatisticResult> result =
orgStatisticService.getOrgTaskStatistics(orgName, startTime, endTime);
return ApiResponse.success(result);
}
/**
* 按区/镇统计任务数量和人员参与情况
*
* @param district 区名称,可选
* @param village 镇名称,可选
* @return 统一返回格式
*/
@GetMapping("/district-statistics")
public ApiResponse<Map<String, TaskStatisticResult>> getDistrictStatistics(
@RequestParam(required = false) String district,
@RequestParam(required = false) String village,
@RequestParam(required = false)
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startTime,
@RequestParam(required = false)
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endTime) {
Map<String, TaskStatisticResult> result =
districtStatisticService.getDistrictTaskStatistics(district, village, startTime, endTime);
return ApiResponse.success(result);
}
/**
* 按人名和时间统计任务情况(遍历全部 schema
*
* @param username 模糊人名,可选
* @return 每个 schema 的统计结果
*/
@GetMapping("/user-statistics")
public ApiResponse<Map<String, TaskStatisticResult>> getUserStatistics(
@RequestParam(required = false) String username,
@RequestParam(required = false)
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime startTime,
@RequestParam(required = false)
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime endTime) {
Map<String, TaskStatisticResult> result =
userStatisticService.getUserTaskStatistics(username,startTime, endTime);
return ApiResponse.success(result);
}
@GetMapping("/dropdown-options")
public ApiResponse<Map<String, List<String>>> getDropdownOptions() {
Map<String, List<String>> result = unitInfoService.getDropdownOptions();
return ApiResponse.success(result);
}
}

View File

@@ -0,0 +1,18 @@
package com.whu.edu.LyStatistic.statistic.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* 根表任务实体类,对应 roottable1。
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class RootTask implements Serializable {
private Long id;
private Long collector;
private Long reviewer;
}

View File

@@ -11,6 +11,9 @@ import java.util.List;
@NoArgsConstructor
public class TaskStatisticResult {
private String schema;
private Integer totalCount;
private List<UserStatistic> userStatistics;
private int totalRootCount;
private int totalT1sub1Count;
private int totalT1sub2Count;
private int totalT1sub3Count;
}

View File

@@ -9,5 +9,9 @@ import lombok.NoArgsConstructor;
@NoArgsConstructor
public class UserStatistic {
private String username;
private Integer taskCount;
// private Integer taskCount;
private int rootCount; // 小班数量roottable1
private int t1sub1Count; // 样地数量
private int t1sub2Count; // 样木数量
private int t1sub3Count; // 灌木数量
}

View File

@@ -1,14 +0,0 @@
package com.whu.edu.LyStatistic.statistic.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
public class UserTaskCount {
private Long userId;
private Integer count;
}

View File

@@ -0,0 +1,16 @@
package com.whu.edu.LyStatistic.statistic.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface DistrictSchemaMapper {
/**
* 根据区/镇获取 schema 列表
* 如果 village 为 null则返回该区下所有 schema
*/
List<String> findSchemasByDistrictAndVillage(@Param("district") String district,
@Param("village") String village);
}

View File

@@ -0,0 +1,13 @@
package com.whu.edu.LyStatistic.statistic.mapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface SchemaMapper {
/**
* 查询所有 schema 名称
*/
List<String> findAllSchemas();
}

View File

@@ -1,25 +1,48 @@
package com.whu.edu.LyStatistic.statistic.mapper;
import org.apache.ibatis.annotations.Mapper;
import com.whu.edu.LyStatistic.statistic.dto.RootTask;
import org.apache.ibatis.annotations.MapKey;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime;
import java.util.List;
import com.whu.edu.LyStatistic.statistic.dto.UserTaskCount;
@Mapper
import java.util.Map;
public interface TaskStatisticMapper {
/**
* 统计 collector 数量
* 查询根表任务(支持时间范围 + 人员过滤)
*/
List<UserTaskCount> countByCollector(@Param("schema") String schema,
@Param("table") String table,
@Param("timeParam") LocalDateTime timeParam,
@Param("userIds") List<Long> userIds);
List<RootTask> findRootTasksByTimeRange(
@Param("schema") String schema,
@Param("startTime") LocalDateTime startTime,
@Param("endTime") LocalDateTime endTime,
@Param("userIds") List<Long> userIds
);
/**
* 统计 reviewer 数量
* 统计子表数量,返回每个 parentID 对应的数量
*/
List<UserTaskCount> countByReviewer(@Param("schema") String schema,
@Param("table") String table,
@Param("timeParam") LocalDateTime timeParam,
@Param("userIds") List<Long> userIds);
List<Map<String, Object>> countGroupByParent(@Param("schema") String schema,
@Param("table") String table,
@Param("column") String column,
@Param("parentIds") List<Long> parentIds);
/**
* 查询子表 ID 列表,并按 parentID 分组
*/
@MapKey("parentid")
List<Map<String, Object>> findSubIdsGroupByParent(@Param("schema") String schema,
@Param("table") String table,
@Param("column") String column,
@Param("parentIds") List<Long> parentIds);
/**
* 查询 t1sub2 子表数量,单个 parentID
*/
Integer countByParentId(@Param("schema") String schema,
@Param("table") String table,
@Param("column") String column,
@Param("parentId") Long parentId);
}

View File

@@ -0,0 +1,14 @@
package com.whu.edu.LyStatistic.statistic.mapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface UnitInfoMapper {
List<String> findDistinctDistricts();
List<String> findDistinctVillages();
List<String> findDistinctUnits();
}

View File

@@ -0,0 +1,45 @@
package com.whu.edu.LyStatistic.statistic.service;
import com.whu.edu.LyStatistic.statistic.dto.TaskStatisticResult;
import com.whu.edu.LyStatistic.statistic.mapper.DistrictSchemaMapper;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class DistrictStatisticService {
private final TaskStatisticService taskStatisticService;
private final DistrictSchemaMapper districtSchemaMapper;
public DistrictStatisticService(TaskStatisticService taskStatisticService,
DistrictSchemaMapper districtSchemaMapper) {
this.taskStatisticService = taskStatisticService;
this.districtSchemaMapper = districtSchemaMapper;
}
/**
* 获取区/镇任务统计
*
* @param district 区名称,可为空
* @param village 镇名称,可为空
*/
public Map<String, TaskStatisticResult> getDistrictTaskStatistics(String district,
String village,
LocalDateTime startTime,
LocalDateTime endTime) {
// 1. 找出该区/镇对应的全部 schema
List<String> schemas = districtSchemaMapper.findSchemasByDistrictAndVillage(district, village);
Map<String, TaskStatisticResult> resultMap = new HashMap<>();
// 2. 遍历 schema调用通用统计方法
for (String schema : schemas) {
TaskStatisticResult stat = taskStatisticService.getStatistics(schema, startTime, endTime, null);
resultMap.put(schema, stat);
}
return resultMap;
}
}

View File

@@ -21,24 +21,19 @@ public class OrgStatisticService {
/**
* 按单位和时间统计任务信息
* @param orgName 单位名称
* @param timeParam 截止时间
* @param tables 根表及子表
* @return Map<schema, TaskStatisticResult>
*/
public Map<String, TaskStatisticResult> getOrgTaskStatistics(String orgName,
LocalDateTime timeParam,
List<String> tables) {
// 1. 获取该单位对应的所有 schema
LocalDateTime startTime,
LocalDateTime endTime) {
// 1. 找到该单位对应的 schema 列表
List<String> schemas = orgSchemaMapper.findSchemasByOrgName(orgName);
if (schemas == null || schemas.isEmpty()) {
return Collections.emptyMap();
}
Map<String, TaskStatisticResult> resultMap = new HashMap<>();
// 2. 循环每个 schema 调用通用统计
Map<String, TaskStatisticResult> resultMap = new LinkedHashMap<>();
// 2. 每个 schema 执行统计方法
for (String schema : schemas) {
TaskStatisticResult result = taskStatisticService.getStatistics(schema, timeParam, null, tables);
resultMap.put(schema, result);
TaskStatisticResult stat = taskStatisticService.getStatistics(schema, startTime, endTime, null);
resultMap.put(schema, stat);
}
return resultMap;

View File

@@ -1,31 +1,39 @@
package com.whu.edu.LyStatistic.statistic.service;
import com.whu.edu.LyStatistic.statistic.dto.*;
import com.whu.edu.LyStatistic.statistic.mapper.TaskStatisticMapper;
import com.whu.edu.LyStatistic.statistic.mapper.UserStaffMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import com.whu.edu.LyStatistic.statistic.dto.UserTaskCount;
import com.whu.edu.LyStatistic.statistic.dto.TaskStatisticResult;
import com.whu.edu.LyStatistic.statistic.dto.UserStatistic;
import com.whu.edu.LyStatistic.statistic.mapper.TaskStatisticMapper;
import com.whu.edu.LyStatistic.statistic.mapper.UserStaffMapper;
import com.whu.edu.LyStatistic.statistic.dto.UserStaff;
import java.util.stream.Stream;
@Service
public class TaskStatisticService {
private final TaskStatisticMapper taskStatisticMapper;
private final UserStaffMapper userStaffMapper;
@Autowired
private UserStaffMapper userStaffMapper;
public TaskStatisticService(TaskStatisticMapper taskStatisticMapper, UserStaffMapper userStaffMapper) {
this.taskStatisticMapper = taskStatisticMapper;
this.userStaffMapper = userStaffMapper;
}
@Autowired
private TaskStatisticMapper taskStatisticMapper;
/**
* 按 schema 和时间区间统计任务数据
*
* @param schema 数据库 schema 名称
* @param startTime 起始时间(可选)
* @param endTime 截止时间(可选)
* @param nameLike 人名模糊查询(可选)
*/
public TaskStatisticResult getStatistics(String schema,
LocalDateTime timeParam,
String nameLike,
List<String> tables) {
LocalDateTime startTime,
LocalDateTime endTime,
String nameLike) {
// 1. 查询模糊匹配人员ID(若有)
// 1️⃣ 模糊匹配人员ID
List<Long> userIds = null;
if (nameLike != null && !nameLike.isEmpty()) {
userIds = userStaffMapper.findByNameLike(nameLike)
@@ -34,38 +42,125 @@ public class TaskStatisticService {
.collect(Collectors.toList());
}
// 2. 按schema统计任务量collector+reviewer
Map<Long, Integer> countMap = new HashMap<>();
for (String table : tables) {
List<UserTaskCount> collectorCounts = taskStatisticMapper.countByCollector(schema, table, timeParam, userIds);
List<UserTaskCount> reviewerCounts = taskStatisticMapper.countByReviewer(schema, table, timeParam, userIds);
for (UserTaskCount c : collectorCounts) {
countMap.merge(c.getUserId(), c.getCount(), Integer::sum);
}
for (UserTaskCount r : reviewerCounts) {
countMap.merge(r.getUserId(), r.getCount(), Integer::sum);
}
// 2️⃣ 查询根表记录(支持时间区间
List<RootTask> rootTasks = taskStatisticMapper.findRootTasksByTimeRange(schema, startTime, endTime, userIds);
if (rootTasks.isEmpty()) {
return new TaskStatisticResult(schema, Collections.emptyList(), 0, 0, 0, 0);
}
if (countMap.isEmpty()) {
return new TaskStatisticResult(schema, 0, Collections.emptyList());
}
// 3. 查询所有 userId 对应 username
List<Long> allUserIds = new ArrayList<>(countMap.keySet());
Map<Long, String> idToName = userStaffMapper.findByIds(allUserIds)
.stream()
.collect(Collectors.toMap(UserStaff::getId, UserStaff::getUsername));
// 4. 构造结果username -> count
List<UserStatistic> userStats = countMap.entrySet().stream()
.map(e -> new UserStatistic(idToName.getOrDefault(e.getKey(), "未知用户"), e.getValue()))
// 3⃣ 获取所有根表ID
List<Long> rootIds = rootTasks.stream()
.map(RootTask::getId)
.filter(Objects::nonNull)
.collect(Collectors.toList());
int total = countMap.values().stream().mapToInt(Integer::intValue).sum();
// 4⃣ 查询子表计数
Map<Long, Integer> t1sub1Map = safeCountByParent(schema, "t1sub1", rootIds);
Map<Long, Integer> t1sub3Map = safeCountByParent(schema, "t1sub3", rootIds);
return new TaskStatisticResult(schema, total, userStats);
// 4.1️⃣ t1sub2 层级统计
List<Map<String, Object>> sub1List = safeFindSubIds(schema, "t1sub1", rootIds);
Map<Long, List<Long>> rootToSub1Ids = rootIds.stream()
.collect(Collectors.toMap(
rid -> rid,
rid -> sub1List.stream()
.filter(m -> m.get("parentid") != null &&
rid.equals(((Number) m.get("parentid")).longValue()))
.map(m -> ((Number) m.get("ID")).longValue())
.collect(Collectors.toList())
));
Map<Long, Integer> t1sub2Map = new HashMap<>();
for (Map.Entry<Long, List<Long>> entry : rootToSub1Ids.entrySet()) {
int total = 0;
for (Long sub1Id : entry.getValue()) {
Integer count = safeCountByParentId(schema, "t1sub2", sub1Id);
total += (count != null) ? count : 0;
}
t1sub2Map.put(entry.getKey(), total);
}
// 5⃣ 汇总用户统计(排除 null 和 -1
Map<Long, UserStatistic> userStats = new HashMap<>();
for (RootTask task : rootTasks) {
Long rootId = task.getId();
if (rootId == null) continue;
Stream.of(task.getCollector(), task.getReviewer())
.filter(uid -> uid != null && uid != -1)
.forEach(uid -> {
UserStatistic stat = userStats.computeIfAbsent(uid, k -> new UserStatistic());
stat.setRootCount(stat.getRootCount() + 1);
stat.setT1sub1Count(stat.getT1sub1Count() + t1sub1Map.getOrDefault(rootId, 0));
stat.setT1sub2Count(stat.getT1sub2Count() + t1sub2Map.getOrDefault(rootId, 0));
stat.setT1sub3Count(stat.getT1sub3Count() + t1sub3Map.getOrDefault(rootId, 0));
});
}
// 6⃣ 填充用户名
Map<Long, String> idToName = new HashMap<>();
if (!userStats.isEmpty()) {
userIds = new ArrayList<>(userStats.keySet());
List<UserStaff> userList = userStaffMapper.findByIds(userIds);
if (userList != null && !userList.isEmpty()) {
idToName = userList.stream()
.filter(u -> u.getId() != null)
.collect(Collectors.toMap(
UserStaff::getId,
UserStaff::getUsername,
(a, b) -> a // 避免重复键
));
}
}
final Map<Long, String> nameMap = idToName; // ✅ 实际 final可安全用于 lambda
List<UserStatistic> results = userStats.entrySet().stream()
.map(e -> {
UserStatistic stat = e.getValue();
stat.setUsername(nameMap.getOrDefault(e.getKey(), "未知用户"));
return stat;
})
.collect(Collectors.toList());
// 7⃣ 总量统计
int totalRootCount = rootTasks.size();
int totalT1sub1Count = t1sub1Map.values().stream().mapToInt(Integer::intValue).sum();
int totalT1sub2Count = t1sub2Map.values().stream().mapToInt(Integer::intValue).sum();
int totalT1sub3Count = t1sub3Map.values().stream().mapToInt(Integer::intValue).sum();
return new TaskStatisticResult(schema, results,
totalRootCount, totalT1sub1Count, totalT1sub2Count, totalT1sub3Count);
}
// 🧩 安全封装:防止 schema 无表时报错
private Map<Long, Integer> safeCountByParent(String schema, String table, List<Long> rootIds) {
try {
return taskStatisticMapper.countGroupByParent(schema, table, "parentID", rootIds)
.stream()
.filter(m -> m.get("parentid") != null)
.collect(Collectors.toMap(
m -> ((Number) m.get("parentid")).longValue(),
m -> ((Number) m.getOrDefault("count", 0)).intValue()
));
} catch (Exception e) {
return new HashMap<>();
}
}
private List<Map<String, Object>> safeFindSubIds(String schema, String table, List<Long> rootIds) {
try {
return taskStatisticMapper.findSubIdsGroupByParent(schema, table, "parentID", rootIds);
} catch (Exception e) {
return Collections.emptyList();
}
}
private Integer safeCountByParentId(String schema, String table, Long parentId) {
try {
return taskStatisticMapper.countByParentId(schema, table, "parentID", parentId);
} catch (Exception e) {
return 0;
}
}
}

View File

@@ -0,0 +1,24 @@
package com.whu.edu.LyStatistic.statistic.service;
import com.whu.edu.LyStatistic.statistic.mapper.UnitInfoMapper;
import org.springframework.stereotype.Service;
import java.util.*;
@Service
public class UnitInfoService {
private final UnitInfoMapper unitInfoMapper;
public UnitInfoService(UnitInfoMapper unitInfoMapper) {
this.unitInfoMapper = unitInfoMapper;
}
public Map<String, List<String>> getDropdownOptions() {
Map<String, List<String>> map = new HashMap<>();
map.put("districts", unitInfoMapper.findDistinctDistricts());
map.put("villages", unitInfoMapper.findDistinctVillages());
map.put("units", unitInfoMapper.findDistinctUnits());
return map;
}
}

View File

@@ -0,0 +1,45 @@
package com.whu.edu.LyStatistic.statistic.service;
import com.whu.edu.LyStatistic.statistic.dto.TaskStatisticResult;
import com.whu.edu.LyStatistic.statistic.mapper.SchemaMapper;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class UserStatisticService {
private final TaskStatisticService taskStatisticService;
private final SchemaMapper schemaMapper;
public UserStatisticService(TaskStatisticService taskStatisticService,
SchemaMapper schemaMapper) {
this.taskStatisticService = taskStatisticService;
this.schemaMapper = schemaMapper;
}
/**
* 按人名和时间统计任务数量
*
* @param username 模糊人名,可选
* @return 各 schema 的统计结果
*/
public Map<String, TaskStatisticResult> getUserTaskStatistics(String username, LocalDateTime startTime,
LocalDateTime endTime) {
// 查询所有 schema
List<String> schemas = schemaMapper.findAllSchemas();
Map<String, TaskStatisticResult> resultMap = new HashMap<>();
for (String schema : schemas) {
// 调用通用统计方法
TaskStatisticResult statistic = taskStatisticService.getStatistics(schema, startTime, endTime, username);
resultMap.put(schema, statistic);
}
return resultMap;
}
}

View File

@@ -4,7 +4,7 @@ server.port=9001
server.address=0.0.0.0
spring.datasource.host=120.48.89.193
spring.datasource.port=5432
spring.datasource.database=tj_lydc
spring.datasource.database=lydc_statistic
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.username=postgres

View File

@@ -0,0 +1,25 @@
<?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.statistic.mapper.DistrictSchemaMapper">
<!--
根据 district 和 village 获取对应的 schema 列表
如果 village 为 null则返回该 district 下所有 schema
schema_name 字段为数据库中存储 schema 名称的字段
-->
<select id="findSchemasByDistrictAndVillage" resultType="string">
SELECT schema_code
FROM public.unit_info
WHERE 1=1
<if test="district != null">
AND district = #{district}
</if>
<if test="village != null">
AND village = #{village}
</if>
</select>
</mapper>

View File

@@ -0,0 +1,14 @@
<?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.statistic.mapper.SchemaMapper">
<!-- 查询全部 schema -->
<select id="findAllSchemas" resultType="string">
SELECT schema_code
FROM public.unit_info
</select>
</mapper>

View File

@@ -4,36 +4,79 @@
<mapper namespace="com.whu.edu.LyStatistic.statistic.mapper.TaskStatisticMapper">
<select id="countByCollector" parameterType="map" resultType="com.whu.edu.LyStatistic.statistic.dto.UserTaskCount">
SELECT collector AS user_id, COUNT(*) AS count
FROM "${schema}"."${table}" t
WHERE t.collector != -1
<!-- 根表记录 -->
<select id="findRootTasks" resultType="com.whu.edu.LyStatistic.statistic.dto.RootTask">
SELECT "ID" AS id,
"collector" AS collector,
"reviewer" AS reviewer
FROM "${schema}".roottable1
WHERE 1=1
<if test="timeParam != null">
AND update_time &lt;= #{timeParam}
AND create_time &gt;= #{timeParam}
</if>
<if test="userIds != null and userIds.size() > 0">
AND collector IN
AND ("collector" IN
<foreach collection="userIds" item="id" open="(" separator="," close=")">
#{id}
</foreach>
OR "reviewer" IN
<foreach collection="userIds" item="id" open="(" separator="," close=")">
#{id}
</foreach>)
</if>
</select>
<select id="findRootTasksByTimeRange" parameterType="map" resultType="com.whu.edu.LyStatistic.statistic.dto.RootTask">
SELECT "ID" AS id,
"collector" AS collector,
"reviewer" AS reviewer,
update_time
FROM "${schema}".roottable1
WHERE 1=1
<if test="startTime != null">
AND update_time &gt;= #{startTime}
</if>
<if test="endTime != null">
AND update_time &lt;= #{endTime}
</if>
<if test="userIds != null and userIds.size() > 0">
AND (collector IN
<foreach collection="userIds" item="id" open="(" separator="," close=")">
#{id}
</foreach>
OR reviewer IN
<foreach collection="userIds" item="id" open="(" separator="," close=")">
#{id}
</foreach>)
</if>
GROUP BY collector
</select>
<select id="countByReviewer" parameterType="map" resultType="com.whu.edu.LyStatistic.statistic.dto.UserTaskCount">
SELECT reviewer AS user_id, COUNT(*) AS count
FROM "${schema}"."${table}" t
WHERE t.reviewer != -1
<if test="timeParam != null">
AND update_time &lt;= #{timeParam}
</if>
<if test="userIds != null and userIds.size() > 0">
AND reviewer IN
<foreach collection="userIds" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</if>
GROUP BY reviewer
<!-- 子表分组计数 -->
<select id="countGroupByParent" resultType="map">
SELECT "${column}" AS parentid,
COUNT(*) AS count
FROM "${schema}".${table}
WHERE "${column}" IN
<foreach collection="parentIds" item="pid" open="(" separator="," close=")">
#{pid}
</foreach>
GROUP BY "${column}"
</select>
<!-- 子表 ID 列表,并按 parentID 分组 -->
<select id="findSubIdsGroupByParent" resultType="map">
SELECT "${column}" AS parentid, "ID"
FROM "${schema}".${table}
WHERE "${column}" IN
<foreach collection="parentIds" item="pid" open="(" separator="," close=")">
#{pid}
</foreach>
</select>
<!-- t1sub2 单个 parentID 计数 -->
<select id="countByParentId" resultType="int">
SELECT COUNT(*)
FROM "${schema}".${table}
WHERE "${column}" = #{parentId}
</select>
</mapper>

View File

@@ -0,0 +1,34 @@
<?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.statistic.mapper.UnitInfoMapper">
<select id="findDistinctDistricts" resultType="string">
<![CDATA[
SELECT DISTINCT district
FROM public.unit_info
WHERE district IS NOT NULL AND district <> ''
ORDER BY district
]]>
</select>
<select id="findDistinctVillages" resultType="string">
<![CDATA[
SELECT DISTINCT village
FROM public.unit_info
WHERE village IS NOT NULL AND village <> ''
ORDER BY village
]]>
</select>
<select id="findDistinctUnits" resultType="string">
<![CDATA[
SELECT DISTINCT unit_name
FROM public.unit_info
WHERE unit_name IS NOT NULL AND unit_name <> ''
ORDER BY unit_name
]]>
</select>
</mapper>

View File

@@ -6,7 +6,7 @@
<!-- 根据用户名模糊查询 -->
<select id="findByNameLike" resultType="com.whu.edu.LyStatistic.statistic.dto.UserStaff">
SELECT id, real_name
SELECT id, real_name AS username
FROM public.user_staff
WHERE real_name ILIKE CONCAT('%', #{name}, '%')
</select>
@@ -20,6 +20,4 @@
#{id}
</foreach>
</select>
</mapper>