init
This commit is contained in:
15
src/main/java/com/whu/edu/LyStatistic/BootApplication.java
Normal file
15
src/main/java/com/whu/edu/LyStatistic/BootApplication.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package com.whu.edu.LyStatistic;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
@MapperScan("com.whu.edu.LyStatistic.*.mapper")
|
||||
public class BootApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(BootApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.whu.edu.LyStatistic.statistic.Util;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
/**
|
||||
* 通用接口返回封装
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ApiResponse<T> {
|
||||
|
||||
private int code;
|
||||
private String message;
|
||||
private T data;
|
||||
|
||||
public static <T> ApiResponse<T> success(T data) {
|
||||
return new ApiResponse<>(0, "success", data);
|
||||
}
|
||||
|
||||
public static <T> ApiResponse<T> success(String message, T data) {
|
||||
return new ApiResponse<>(0, message, data);
|
||||
}
|
||||
|
||||
public static <T> ApiResponse<T> error(int code, String message) {
|
||||
return new ApiResponse<>(code, message, null);
|
||||
}
|
||||
|
||||
public static <T> ApiResponse<T> error(String message) {
|
||||
return new ApiResponse<>(500, message, null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.whu.edu.LyStatistic.statistic.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class TaskStatisticResult {
|
||||
private String schema;
|
||||
private Integer totalCount;
|
||||
private List<UserStatistic> userStatistics;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.whu.edu.LyStatistic.statistic.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class UserStaff {
|
||||
private Long id;
|
||||
private String username;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.whu.edu.LyStatistic.statistic.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class UserStatistic {
|
||||
private String username;
|
||||
private Integer taskCount;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
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 OrgSchemaMapper {
|
||||
List<String> findSchemasByOrgName(@Param("orgName") String orgName);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.whu.edu.LyStatistic.statistic.mapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import com.whu.edu.LyStatistic.statistic.dto.UserTaskCount;
|
||||
@Mapper
|
||||
public interface TaskStatisticMapper {
|
||||
|
||||
/**
|
||||
* 统计 collector 数量
|
||||
*/
|
||||
List<UserTaskCount> countByCollector(@Param("schema") String schema,
|
||||
@Param("table") String table,
|
||||
@Param("timeParam") LocalDateTime timeParam,
|
||||
@Param("userIds") List<Long> userIds);
|
||||
|
||||
/**
|
||||
* 统计 reviewer 数量
|
||||
*/
|
||||
List<UserTaskCount> countByReviewer(@Param("schema") String schema,
|
||||
@Param("table") String table,
|
||||
@Param("timeParam") LocalDateTime timeParam,
|
||||
@Param("userIds") List<Long> userIds);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.whu.edu.LyStatistic.statistic.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import com.whu.edu.LyStatistic.statistic.dto.UserStaff;
|
||||
import java.util.List;
|
||||
@Mapper
|
||||
public interface UserStaffMapper {
|
||||
List<UserStaff> findByNameLike(@Param("name") String name);
|
||||
List<UserStaff> findByIds(@Param("ids") List<Long> ids);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.whu.edu.LyStatistic.statistic.service;
|
||||
|
||||
import com.whu.edu.LyStatistic.statistic.dto.TaskStatisticResult;
|
||||
import com.whu.edu.LyStatistic.statistic.mapper.OrgSchemaMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
|
||||
@Service
|
||||
public class OrgStatisticService {
|
||||
|
||||
private final OrgSchemaMapper orgSchemaMapper;
|
||||
private final TaskStatisticService taskStatisticService;
|
||||
|
||||
public OrgStatisticService(OrgSchemaMapper orgSchemaMapper, TaskStatisticService taskStatisticService) {
|
||||
this.orgSchemaMapper = orgSchemaMapper;
|
||||
this.taskStatisticService = taskStatisticService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按单位和时间统计任务信息
|
||||
* @param orgName 单位名称
|
||||
* @param timeParam 截止时间
|
||||
* @param tables 根表及子表
|
||||
* @return Map<schema, TaskStatisticResult>
|
||||
*/
|
||||
public Map<String, TaskStatisticResult> getOrgTaskStatistics(String orgName,
|
||||
LocalDateTime timeParam,
|
||||
List<String> tables) {
|
||||
// 1. 获取该单位对应的所有 schema
|
||||
List<String> schemas = orgSchemaMapper.findSchemasByOrgName(orgName);
|
||||
if (schemas == null || schemas.isEmpty()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
// 2. 循环每个 schema 调用通用统计
|
||||
Map<String, TaskStatisticResult> resultMap = new LinkedHashMap<>();
|
||||
for (String schema : schemas) {
|
||||
TaskStatisticResult result = taskStatisticService.getStatistics(schema, timeParam, null, tables);
|
||||
resultMap.put(schema, result);
|
||||
}
|
||||
|
||||
return resultMap;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.whu.edu.LyStatistic.statistic.service;
|
||||
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;
|
||||
@Service
|
||||
public class TaskStatisticService {
|
||||
|
||||
private final TaskStatisticMapper taskStatisticMapper;
|
||||
private final UserStaffMapper userStaffMapper;
|
||||
|
||||
public TaskStatisticService(TaskStatisticMapper taskStatisticMapper, UserStaffMapper userStaffMapper) {
|
||||
this.taskStatisticMapper = taskStatisticMapper;
|
||||
this.userStaffMapper = userStaffMapper;
|
||||
}
|
||||
|
||||
public TaskStatisticResult getStatistics(String schema,
|
||||
LocalDateTime timeParam,
|
||||
String nameLike,
|
||||
List<String> tables) {
|
||||
|
||||
// 1. 查询模糊匹配的人员ID(若有)
|
||||
List<Long> userIds = null;
|
||||
if (nameLike != null && !nameLike.isEmpty()) {
|
||||
userIds = userStaffMapper.findByNameLike(nameLike)
|
||||
.stream()
|
||||
.map(UserStaff::getId)
|
||||
.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);
|
||||
}
|
||||
}
|
||||
|
||||
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()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
int total = countMap.values().stream().mapToInt(Integer::intValue).sum();
|
||||
|
||||
return new TaskStatisticResult(schema, total, userStats);
|
||||
}
|
||||
}
|
||||
20
src/main/resources/application.properties
Normal file
20
src/main/resources/application.properties
Normal file
@@ -0,0 +1,20 @@
|
||||
spring.application.name=LydcStatistic
|
||||
spring.profiles.active=dev
|
||||
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.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
|
||||
spring.datasource.password=503503
|
||||
spring.datasource.hikari.minimum-idle=5
|
||||
spring.datasource.hikari.idle-timeout=180000
|
||||
spring.datasource.hikari.maximum-pool-size=30
|
||||
spring.datasource.hikari.max-lifetime=1800000
|
||||
spring.datasource.hikari.connection-timeout=30000
|
||||
logging.level.cn.edu.whu.boot.*.mapper=debug
|
||||
mybatis.mapper-locations=classpath:mapper/**/*.xml
|
||||
mybatis.configuration.map-underscore-to-camel-case=true
|
||||
|
||||
11
src/main/resources/mapper/OrgSchemaMapper.xml
Normal file
11
src/main/resources/mapper/OrgSchemaMapper.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?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.OrgSchemaMapper">
|
||||
<select id="findSchemasByOrgName" resultType="string">
|
||||
SELECT schema_code
|
||||
FROM public.unit_info
|
||||
WHERE unit_name = #{orgName}
|
||||
</select>
|
||||
</mapper>
|
||||
39
src/main/resources/mapper/TaskStatisticMapper.xml
Normal file
39
src/main/resources/mapper/TaskStatisticMapper.xml
Normal file
@@ -0,0 +1,39 @@
|
||||
<?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.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
|
||||
<if test="timeParam != null">
|
||||
AND update_time <= #{timeParam}
|
||||
</if>
|
||||
<if test="userIds != null and userIds.size() > 0">
|
||||
AND collector 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 <= #{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>
|
||||
|
||||
</mapper>
|
||||
25
src/main/resources/mapper/UserStaffMapper.xml
Normal file
25
src/main/resources/mapper/UserStaffMapper.xml
Normal 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.UserStaffMapper">
|
||||
|
||||
<!-- 根据用户名模糊查询 -->
|
||||
<select id="findByNameLike" resultType="com.whu.edu.LyStatistic.statistic.dto.UserStaff">
|
||||
SELECT id, real_name
|
||||
FROM public.user_staff
|
||||
WHERE real_name ILIKE CONCAT('%', #{name}, '%')
|
||||
</select>
|
||||
|
||||
<!-- 根据 ID 查询 -->
|
||||
<select id="findByIds" resultType="com.whu.edu.LyStatistic.statistic.dto.UserStaff">
|
||||
SELECT id, real_name AS username
|
||||
FROM public.user_staff
|
||||
WHERE id IN
|
||||
<foreach collection="ids" item="id" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.whu.edu.LyStatistic;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class DemoApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user