fix: 优化到数统计接口逻辑

This commit is contained in:
tangwei 2026-05-13 15:54:04 +08:00
parent 3d48fb05b4
commit 85434d4d33
7 changed files with 177 additions and 155 deletions

View File

@ -1,44 +0,0 @@
package com.yfd.platform.config;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 将以 /prod-api/ 开头的请求转发到去掉前缀的真实后端接口路径
* 例如/prod-api/user/code -> /user/code
* 这样可以兼容前端生产环境仍使用 /prod-api 作为网关前缀的情况
*/
@WebFilter(urlPatterns = "/prod-api/*", filterName = "prodApiPrefixFilter")
public class ProdApiPrefixFilter implements Filter {
private static final String PREFIX = "/prod-api";
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
if (!(req instanceof HttpServletRequest) || !(res instanceof HttpServletResponse)) {
chain.doFilter(req, res);
return;
}
HttpServletRequest request = (HttpServletRequest) req;
String uri = request.getRequestURI();
// 仅拦截 /prod-api/* 的接口请求并进行内部 forward
if (uri.startsWith(PREFIX + "/")) {
String forwardUri = uri.substring(PREFIX.length());
RequestDispatcher dispatcher = request.getRequestDispatcher(forwardUri);
dispatcher.forward(req, res);
return;
}
chain.doFilter(req, res);
}
}

View File

@ -22,6 +22,10 @@ public class FishStatisticsVO implements Serializable {
private String stationNames;
private String basinCode;
private String stationCode;
private String reportMonth;
private Date minStrdt;

View File

@ -7,11 +7,11 @@ import java.util.List;
public interface FishStatisticsMapper {
List<FishStatisticsVO> queryStatistics(@Param("basinNames") List<String> basinNames,
@Param("stationNames") List<String> stationNames,
List<FishStatisticsVO> queryStatistics(@Param("basinCode") String basinCode,
@Param("stationCode") String stationCode,
@Param("startRow") int startRow,
@Param("endRow") int endRow);
int countStatistics(@Param("basinNames") List<String> basinNames,
@Param("stationNames") List<String> stationNames);
int countStatistics(@Param("basinCode") String basinCode,
@Param("stationCode") String stationCode);
}

View File

@ -28,11 +28,11 @@ public class FishStatisticsServiceImpl implements IFishStatisticsService {
public Page<FishStatisticsVO> queryPage(DataSourceRequest dataSourceRequest) {
DataSourceLoadOptionsBase loadOptions = dataSourceRequest.toDevRequest();
String basinNamesStr = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "basinNames");
String stationNamesStr = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "stationNames");
String basinNamesStr = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "basinCode");
String stationNamesStr = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "stationCode");
List<String> basinNames = parseFilterList(basinNamesStr);
List<String> stationNames = parseFilterList(stationNamesStr);
// List<String> basinNames = parseFilterList(basinNamesStr);
// List<String> stationNames = parseFilterList(stationNamesStr);
int take = dataSourceRequest.getTake();
int skip = dataSourceRequest.getSkip();
@ -44,9 +44,9 @@ public class FishStatisticsServiceImpl implements IFishStatisticsService {
int endRow = skip + take;
List<FishStatisticsVO> records = fishStatisticsMapper.queryStatistics(
basinNames, stationNames, startRow, endRow);
basinNamesStr, stationNamesStr, startRow, endRow);
int total = fishStatisticsMapper.countStatistics(basinNames, stationNames);
int total = fishStatisticsMapper.countStatistics(basinNamesStr, basinNamesStr);
Page<FishStatisticsVO> page = new Page<>();
page.setRecords(records);

View File

@ -1,5 +1,8 @@
server:
port: 8093
tomcat:
connection-timeout: 300000
max-swallow-size: 500MB
spring:
#应用名称
@ -112,6 +115,9 @@ spring:
multipart:
max-file-size: 300MB
max-request-size: 500MB
file-size-threshold: 1KB
location: /tmp/upload
resolve-lazily: true
logging:
file:

View File

@ -1,8 +1,8 @@
server:
port: 8093
tomcat:
max-http-form-post-size: 500MB # Tomcat 表单体大小限制
connection-timeout: 120000 # 连接超时(毫秒),大文件上传需要更长
connection-timeout: 300000
max-swallow-size: 500MB
spring:
#应用名称
application:

View File

@ -10,6 +10,8 @@
<result column="CONTACT" property="contact"/>
<result column="BASIN_NAMES" property="basinNames"/>
<result column="STATION_NAMES" property="stationNames"/>
<result column="BASIN_CODE" property="basinCode"/>
<result column="STATION_CODE" property="stationCode"/>
<result column="REPORT_MONTH" property="reportMonth"/>
<result column="MIN_STRDT" property="minStrdt"/>
<result column="MAX_ENDDT" property="maxEnddt"/>
@ -17,117 +19,171 @@
</resultMap>
<sql id="statisticsQuery">
WITH user_scope_detail AS (
SELECT DISTINCT
su.ID AS USER_ID,
h.HBRVNM AS BASIN_NAME,
e.ENNM AS STATION_NAME
FROM QGC_REFA.SYS_USER su
JOIN QGC_REFA.SYS_USER_DATA_SCOPE sud
ON su.ID = sud.USER_ID
AND sud.STATUS = 1
AND sud.ORG_TYPE = 'HBRVCD'
JOIN QGC_REFA.SD_HBRV_DIC h
ON sud.ORG_ID = h.HBRVCD
AND h.ENABLED = 1
AND h.IS_DELETED = 0
JOIN QGC_REFA.SD_ENGINFO_B_H e
ON e.HBRVCD = h.HBRVCD
AND e.USFL = 1
WHERE su.STATUS = 1
AND su.REG_STATUS IN ('PENDING', 'APPROVED', 'REJECTED')
WITH
user_scope_detail AS (
SELECT DISTINCT
su.ID AS USER_ID,
e.STCD AS STATION_CODE,
h.HBRVCD AS BASIN_CODE,
h.HBRVNM AS BASIN_NAME,
e.ENNM AS STATION_NAME
FROM QGC_REFA.SYS_USER su
JOIN QGC_REFA.SYS_USER_DATA_SCOPE sud
ON su.ID = sud.USER_ID
AND sud.STATUS = 1
AND sud.ORG_TYPE = 'HBRVCD'
JOIN QGC_REFA.SD_HBRV_DIC h
ON sud.ORG_ID = h.HBRVCD
AND h.ENABLED = 1
AND h.IS_DELETED = 0
JOIN QGC_REFA.SD_ENGINFO_B_H e
ON e.HBRVCD = h.HBRVCD
AND e.USFL = 1
WHERE su.STATUS = 1
AND su.REG_STATUS IN ('PENDING', 'APPROVED', 'REJECTED')
UNION
UNION
SELECT DISTINCT
su.ID AS USER_ID,
h.HBRVNM AS BASIN_NAME,
e.ENNM AS STATION_NAME
FROM QGC_REFA.SYS_USER su
JOIN QGC_REFA.SYS_USER_DATA_SCOPE sud
ON su.ID = sud.USER_ID
AND sud.STATUS = 1
AND sud.ORG_TYPE = 'STATION'
JOIN QGC_REFA.SD_ENGINFO_B_H e
ON sud.ORG_ID = e.STCD
AND e.USFL = 1
JOIN QGC_REFA.SD_HBRV_DIC h
ON e.HBRVCD = h.HBRVCD
AND h.ENABLED = 1
AND h.IS_DELETED = 0
WHERE su.STATUS = 1
AND su.REG_STATUS IN ('PENDING', 'APPROVED', 'REJECTED')
SELECT DISTINCT
su.ID AS USER_ID,
e.STCD AS STATION_CODE,
h.HBRVCD AS BASIN_CODE,
h.HBRVNM AS BASIN_NAME,
e.ENNM AS STATION_NAME
FROM QGC_REFA.SYS_USER su
JOIN QGC_REFA.SYS_USER_DATA_SCOPE sud
ON su.ID = sud.USER_ID
AND sud.STATUS = 1
AND sud.ORG_TYPE = 'STATION'
JOIN QGC_REFA.SD_ENGINFO_B_H e
ON sud.ORG_ID = e.STCD
AND e.USFL = 1
JOIN QGC_REFA.SD_HBRV_DIC h
ON e.HBRVCD = h.HBRVCD
AND h.ENABLED = 1
AND h.IS_DELETED = 0
WHERE su.STATUS = 1
AND su.REG_STATUS IN ('PENDING', 'APPROVED', 'REJECTED')
),
user_scope AS (
SELECT
USER_ID,
RTRIM(
XMLAGG(XMLELEMENT(E, BASIN_NAME || ',') ORDER BY BASIN_NAME)
.EXTRACT('//text()').GETCLOBVAL(),
','
) AS BASIN_NAMES,
RTRIM(
XMLAGG(XMLELEMENT(E, STATION_NAME || ',') ORDER BY STATION_NAME)
.EXTRACT('//text()').GETCLOBVAL(),
','
) AS STATION_NAMES
FROM user_scope_detail
GROUP BY USER_ID
filtered_users AS (
SELECT DISTINCT USER_ID
FROM user_scope_detail
<where>
<if test="basinCode != null and basinCode != ''">
AND BASIN_CODE = #{basinCode}
</if>
<if test="stationCode != null and stationCode != ''">
AND STATION_CODE = #{stationCode}
</if>
</where>
),
fish_monthly AS (
SELECT
CREATED_BY,
TO_CHAR(STRDT, 'YYYY-MM') AS REPORT_MONTH,
MIN(STRDT) AS MIN_STRDT,
MAX(STRDT) AS MAX_ENDDT,
SUM(FCNT) AS TOTAL_FCNT
FROM QGC_REFA.FISH_DRAFT_DATA
WHERE DELETED_FLAG = 0 AND STATUS IN ('PENDING','APPROVED')
GROUP BY CREATED_BY, TO_CHAR(STRDT, 'YYYY-MM')
)
distinct_basins AS (
SELECT DISTINCT USER_ID,BASIN_CODE, BASIN_NAME
FROM user_scope_detail
WHERE USER_ID IN (SELECT USER_ID FROM filtered_users)
),
distinct_stations AS (
SELECT DISTINCT USER_ID, STATION_CODE, STATION_NAME
FROM user_scope_detail
WHERE USER_ID IN (SELECT USER_ID FROM filtered_users)
),
basin_agg AS (
SELECT
us.USER_ID,
su.REAL_NAME,
su.PHONE,
su.NICKNAME || '/' || su.PHONE AS CONTACT,
us.BASIN_NAMES,
us.STATION_NAMES,
fm.REPORT_MONTH,
fm.MIN_STRDT,
fm.MAX_ENDDT,
fm.TOTAL_FCNT
FROM user_scope us
USER_ID,
RTRIM(
XMLAGG(XMLELEMENT(E, BASIN_NAME || ',') ORDER BY BASIN_NAME)
.EXTRACT('//text()').GETCLOBVAL(),
','
) AS BASIN_NAMES,
MIN(BASIN_CODE) AS MIN_BASIN_CODE -- 辅助排序字段VARCHAR2
FROM distinct_basins
GROUP BY USER_ID
),
station_agg AS (
SELECT
USER_ID,
RTRIM(
XMLAGG(XMLELEMENT(E, STATION_NAME || ',') ORDER BY STATION_NAME)
.EXTRACT('//text()').GETCLOBVAL(),
','
) AS STATION_NAMES,
MIN(STATION_CODE) AS MIN_STATION_CODE -- 辅助排序字段VARCHAR2
FROM distinct_stations
GROUP BY USER_ID
),
fish_monthly AS (
SELECT
CREATED_BY,
TO_CHAR(STRDT, 'YYYY-MM') AS REPORT_MONTH,
MIN(STRDT) AS MIN_STRDT,
MAX(STRDT) AS MAX_ENDDT,
SUM(FCNT) AS TOTAL_FCNT
FROM QGC_REFA.FISH_DRAFT_DATA
WHERE DELETED_FLAG = 0
AND STATUS IN ('PENDING','APPROVED')
GROUP BY CREATED_BY, TO_CHAR(STRDT, 'YYYY-MM')
),
all_users AS (
SELECT USER_ID FROM filtered_users
)
SELECT
u.USER_ID,
su.REAL_NAME,
su.PHONE,
su.NICKNAME || '/' || su.PHONE AS CONTACT,
ba.MIN_BASIN_CODE,
sa.MIN_STATION_CODE,
ba.BASIN_NAMES,
sa.STATION_NAMES,
fm.REPORT_MONTH,
fm.MIN_STRDT,
fm.MAX_ENDDT,
fm.TOTAL_FCNT
FROM all_users u
JOIN QGC_REFA.SYS_USER su
ON us.USER_ID = su.ID
ON u.USER_ID = su.ID
LEFT JOIN basin_agg ba
ON u.USER_ID = ba.USER_ID
LEFT JOIN station_agg sa
ON u.USER_ID = sa.USER_ID
LEFT JOIN fish_monthly fm
ON us.USER_ID = fm.CREATED_BY
WHERE 1 = 1
<if test="basinNames != null and basinNames.size() > 0">
AND (
<foreach collection="basinNames" item="name" separator=" OR ">
INSTR(us.BASIN_NAMES, #{name}) > 0
</foreach>
)
</if>
<if test="stationNames != null and stationNames.size() > 0">
AND (
<foreach collection="stationNames" item="name" separator=" OR ">
INSTR(us.STATION_NAMES, #{name}) > 0
</foreach>
)
</if>
ORDER BY fm.REPORT_MONTH, us.USER_ID
ON u.USER_ID = fm.CREATED_BY
<!-- 可选排序 -->
<!-- <if test="basinNames != null and basinNames.size() > 0">-->
<!-- AND (-->
<!-- <foreach collection="basinNames" item="name" separator=" OR ">-->
<!-- INSTR(ba.BASIN_NAMES, #{name}) > 0-->
<!-- </foreach>-->
<!-- )-->
<!-- </if>-->
<!-- <if test="stationNames != null and stationNames.size() > 0">-->
<!-- AND (-->
<!-- <foreach collection="stationNames" item="name" separator=" OR ">-->
<!-- INSTR(sa.STATION_NAMES, #{name}) > 0-->
<!-- </foreach>-->
<!-- )-->
<!-- </if>-->
</sql>
<select id="queryStatistics" resultMap="StatisticsResultMap">
SELECT * FROM (
SELECT t.*, ROWNUM rn FROM (
<include refid="statisticsQuery"/>
) t
WHERE ROWNUM &lt;= #{endRow}
) WHERE rn &gt; #{startRow}
SELECT
t.*,
ROW_NUMBER() OVER (ORDER BY t.REPORT_MONTH, t.USER_ID) AS rn
FROM (
<include refid="statisticsQuery"/>
) t ORDER BY t.MIN_BASIN_CODE,t.MIN_STATION_CODE,t.REPORT_MONTH,t.MIN_STRDT
) WHERE rn BETWEEN #{startRow}+1 AND #{endRow}
</select>
<select id="countStatistics" resultType="int">
SELECT COUNT(*) FROM (
<include refid="statisticsQuery"/>