fix: bound dashboard monitoring queries
This commit is contained in:
@@ -19,7 +19,6 @@ import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -55,8 +54,8 @@ public class IndexController extends BaseController {
|
||||
@Anonymous
|
||||
@GetMapping("/bill/status")
|
||||
public AjaxResult getBillStatusCount() {
|
||||
// Temporarily bypass the three unbounded bill queries while diagnosing dashboard latency.
|
||||
return success(Collections.emptyList());
|
||||
List<BillStatusCount> list = billStatusCountService.selectAllBillStatusCount(new BaseEntity());
|
||||
return success(list);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,23 +10,7 @@ import java.util.List;
|
||||
*/
|
||||
public interface BillStatusCountMapper {
|
||||
/**
|
||||
* 查询入库单据状态统计
|
||||
*
|
||||
* @return 入库单据状态统计列表
|
||||
* 查询最近的入库、出库和盘点单据。
|
||||
*/
|
||||
public List<BillStatusCount> selectStockinStatusCount(BaseEntity baseEntity);
|
||||
|
||||
/**
|
||||
* 查询出库单据状态统计
|
||||
*
|
||||
* @return 出库单据状态统计列表
|
||||
*/
|
||||
public List<BillStatusCount> selectStockoutStatusCount(BaseEntity baseEntity);
|
||||
|
||||
/**
|
||||
* 查询盘点单据状态统计
|
||||
*
|
||||
* @return 盘点单据状态统计列表
|
||||
*/
|
||||
public List<BillStatusCount> selectStockcheckStatusCount(BaseEntity baseEntity);
|
||||
List<BillStatusCount> selectRecentBillStatus(BaseEntity baseEntity);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import com.ruoyi.index.service.IBillStatusCountService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -28,29 +27,6 @@ public class BillStatusCountServiceImpl implements IBillStatusCountService {
|
||||
@DataScope
|
||||
// @DataScope(warehouseAlias = "")
|
||||
public List<BillStatusCount> selectAllBillStatusCount(BaseEntity baseEntity) {
|
||||
List<BillStatusCount> resultList = new ArrayList<>();
|
||||
|
||||
// 查询入库单据状态统计
|
||||
List<BillStatusCount> stockinList = billStatusCountMapper.selectStockinStatusCount(baseEntity);
|
||||
if (stockinList != null) {
|
||||
resultList.addAll(stockinList);
|
||||
}
|
||||
|
||||
// 查询出库单据状态统计
|
||||
List<BillStatusCount> stockoutList = billStatusCountMapper.selectStockoutStatusCount(baseEntity);
|
||||
if (stockoutList != null) {
|
||||
resultList.addAll(stockoutList);
|
||||
}
|
||||
|
||||
// 查询盘点单据状态统计
|
||||
List<BillStatusCount> stockcheckList = billStatusCountMapper.selectStockcheckStatusCount(baseEntity);
|
||||
if (stockcheckList != null) {
|
||||
resultList.addAll(stockcheckList);
|
||||
}
|
||||
|
||||
// 按照status降序排序(3、2、1)
|
||||
resultList.sort((a, b) -> b.getStatus().compareTo(a.getStatus()));
|
||||
|
||||
return resultList;
|
||||
return billStatusCountMapper.selectRecentBillStatus(baseEntity);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ public class RequestLogController extends BaseController
|
||||
public AjaxResult getMethod()
|
||||
{
|
||||
List<String> strings=requestLogService.getMethod();
|
||||
return AjaxResult.success(requestLogService.getMethod());
|
||||
return AjaxResult.success(strings);
|
||||
}
|
||||
|
||||
// 获取原系统
|
||||
@@ -101,14 +101,14 @@ public class RequestLogController extends BaseController
|
||||
public AjaxResult getSource()
|
||||
{
|
||||
List<String> strings=requestLogService.getSource();
|
||||
return AjaxResult.success(requestLogService.getSource());
|
||||
return AjaxResult.success(strings);
|
||||
}
|
||||
// 获取目标系统
|
||||
@GetMapping("/getTarget")
|
||||
public AjaxResult getTarget()
|
||||
{
|
||||
List<String> strings=requestLogService.getTarget();
|
||||
return AjaxResult.success(requestLogService.getTarget());
|
||||
return AjaxResult.success(strings);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -10,25 +10,37 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="type" column="type"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="selectStockinStatusCount" resultMap="BillStatusCountResult">
|
||||
select stockin_id as id, status, '1' as type
|
||||
from in_stockin
|
||||
where status in ('1', '2', '3')
|
||||
${params.warehouseDataScope}
|
||||
<select id="selectRecentBillStatus" parameterType="BaseEntity" resultMap="BillStatusCountResult">
|
||||
select top (30) id, status, type
|
||||
from (
|
||||
select id, status, type, create_date
|
||||
from (
|
||||
select top (30) stockin_id as id, status, '1' as type, create_date
|
||||
from in_stockin
|
||||
where status in ('1', '2', '3')
|
||||
${params.warehouseDataScope}
|
||||
order by create_date desc, stockin_id desc
|
||||
) recent_stockin
|
||||
union all
|
||||
select id, status, type, create_date
|
||||
from (
|
||||
select top (30) stockout_id as id, status, '2' as type, create_date
|
||||
from out_stockout
|
||||
where status in ('1', '2', '3')
|
||||
${params.warehouseDataScope}
|
||||
order by create_date desc, stockout_id desc
|
||||
) recent_stockout
|
||||
union all
|
||||
select id, status, type, create_date
|
||||
from (
|
||||
select top (30) stock_check_id as id, status, '3' as type, create_date
|
||||
from check_stockin
|
||||
where status in ('1', '2', '3')
|
||||
${params.warehouseDataScope}
|
||||
order by create_date desc, stock_check_id desc
|
||||
) recent_stockcheck
|
||||
) recent_bill
|
||||
order by create_date desc, id desc
|
||||
</select>
|
||||
|
||||
<select id="selectStockoutStatusCount" resultMap="BillStatusCountResult">
|
||||
select stockout_id as id, status, '2' as type
|
||||
from out_stockout
|
||||
where status in ('1', '2', '3')
|
||||
${params.warehouseDataScope}
|
||||
</select>
|
||||
|
||||
<select id="selectStockcheckStatusCount" resultMap="BillStatusCountResult">
|
||||
select stock_check_id as id, status, '3' as type
|
||||
from check_stockin
|
||||
where status in ('1', '2', '3')
|
||||
${params.warehouseDataScope}
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
</mapper>
|
||||
|
||||
@@ -27,7 +27,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</sql>
|
||||
|
||||
<select id="selectRequestLogList" parameterType="RequestLog" resultMap="RequestLogResult">
|
||||
<include refid="selectRequestLogVo"/>
|
||||
select log.request_id, log.request_time, log.source_system, log.target_system, log.endpoint,
|
||||
log.request_url, log.request_method, log.request_headers, log.request_body,
|
||||
log.response_time, log.response_body, log.response_status, log.error_details,
|
||||
log.duration, log.Is_successful
|
||||
from (
|
||||
select top (10000) request_id as recent_request_id
|
||||
from request_log
|
||||
order by request_id desc
|
||||
) recent_log
|
||||
inner join request_log log on log.request_id = recent_log.recent_request_id
|
||||
<where>
|
||||
<if test="requestTime != null and requestTime != ''"> and request_time like concat('%', #{requestTime}, '%')</if>
|
||||
<if test="sourceSystem != null and sourceSystem != ''"> and source_system like concat('%', #{sourceSystem}, '%')</if>
|
||||
@@ -44,6 +53,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="duration != null and duration != ''"> and duration like concat('%', #{duration}, '%')</if>
|
||||
<if test="isSuccessful != null and isSuccessful != ''"> and Is_successful like concat('%', #{isSuccessful}, '%')</if>
|
||||
</where>
|
||||
order by request_id desc
|
||||
</select>
|
||||
|
||||
<select id="selectRequestLogByRequestId" parameterType="Long" resultMap="RequestLogResult">
|
||||
@@ -113,14 +123,35 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</delete>
|
||||
|
||||
<select id="getMethod" resultType="string">
|
||||
select endpoint from request_log group by endpoint
|
||||
select distinct endpoint
|
||||
from (
|
||||
select top (10000) request_id, endpoint
|
||||
from request_log
|
||||
order by request_id desc
|
||||
) recent_log
|
||||
where endpoint is not null
|
||||
order by endpoint
|
||||
</select>
|
||||
|
||||
<select id="getSource" resultType="string">
|
||||
select source_system from request_log group by source_system
|
||||
select distinct source_system
|
||||
from (
|
||||
select top (10000) request_id, source_system
|
||||
from request_log
|
||||
order by request_id desc
|
||||
) recent_log
|
||||
where source_system is not null
|
||||
order by source_system
|
||||
</select>
|
||||
<select id="getTarget" resultType="string">
|
||||
select target_system from request_log group by target_system
|
||||
select distinct target_system
|
||||
from (
|
||||
select top (10000) request_id, target_system
|
||||
from request_log
|
||||
order by request_id desc
|
||||
) recent_log
|
||||
where target_system is not null
|
||||
order by target_system
|
||||
</select>
|
||||
|
||||
<delete id="deleteRequestLogByRequestIds" parameterType="String">
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.ruoyi.index;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class BoundedDashboardQueryTest {
|
||||
private final Path root = projectRoot();
|
||||
|
||||
@Test
|
||||
void dashboardBillEndpointUsesBoundedServiceQuery() throws IOException {
|
||||
String controller = text("ruoyi-admin/src/main/java/com/ruoyi/index/controller/IndexController.java");
|
||||
String mapper = normalized("ruoyi-admin/src/main/resources/mapper/index/BillStatusCountMapper.xml");
|
||||
|
||||
assertThat(controller).contains(
|
||||
"billStatusCountService.selectAllBillStatusCount(new BaseEntity())",
|
||||
"return success(list);");
|
||||
assertThat(controller).doesNotContain("Collections.emptyList()");
|
||||
assertThat(occurrences(mapper, "top (30)")).isEqualTo(4);
|
||||
assertThat(mapper).contains("union all", "order by create_date desc, id desc");
|
||||
assertThat(occurrences(mapper, "${params.warehousedatascope}")).isEqualTo(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
void requestLogPageAndOptionsAreBoundedToRecentRows() throws IOException {
|
||||
String mapper = normalized("ruoyi-admin/src/main/resources/mapper/requestInterface/RequestLogMapper.xml");
|
||||
String controller = text("ruoyi-admin/src/main/java/com/ruoyi/log/controller/RequestLogController.java");
|
||||
|
||||
assertThat(occurrences(mapper, "top (10000)")).isEqualTo(4);
|
||||
assertThat(mapper).contains("order by request_id desc");
|
||||
assertThat(mapper).contains(
|
||||
"inner join request_log log on log.request_id = recent_log.recent_request_id",
|
||||
"select top (10000) request_id as recent_request_id");
|
||||
assertThat(mapper).contains(
|
||||
"select distinct endpoint",
|
||||
"select distinct source_system",
|
||||
"select distinct target_system");
|
||||
assertThat(occurrences(controller, "requestLogService.getMethod()")).isEqualTo(1);
|
||||
assertThat(occurrences(controller, "requestLogService.getSource()")).isEqualTo(1);
|
||||
assertThat(occurrences(controller, "requestLogService.getTarget()")).isEqualTo(1);
|
||||
}
|
||||
|
||||
private String text(String relativePath) throws IOException {
|
||||
return Files.readString(root.resolve(relativePath), StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
private String normalized(String relativePath) throws IOException {
|
||||
return text(relativePath).replaceAll("\\s+", " ").toLowerCase(Locale.ROOT);
|
||||
}
|
||||
|
||||
private int occurrences(String value, String token) {
|
||||
return (value.length() - value.replace(token, "").length()) / token.length();
|
||||
}
|
||||
|
||||
private Path projectRoot() {
|
||||
Path current = Path.of("").toAbsolutePath().normalize();
|
||||
while (current != null && !Files.exists(current.resolve("ruoyi-admin/pom.xml"))) {
|
||||
current = current.getParent();
|
||||
}
|
||||
if (current == null) {
|
||||
throw new IllegalStateException("Could not locate project root");
|
||||
}
|
||||
return current;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user