fix(security): 修复SQL注入+字段引用错误

This commit is contained in:
2026-06-18 20:08:49 +08:00
parent 7cf7d42a31
commit 87f8840d57
9 changed files with 8 additions and 164 deletions

View File

@@ -5,7 +5,5 @@ import java.util.Map;
public interface IInfectionDetailAppService {
Map<String, Object> getInfectionRateByDept(Long deptId);
List<Map<String, Object>> getInfectionTrend(String startDate, String endDate);
}

View File

@@ -18,43 +18,6 @@ public class InfectionDetailAppServiceImpl implements IInfectionDetailAppService
private final IHirInfectionCaseService infectionCaseService;
@Override
public Map<String, Object> getInfectionRateByDept(Long deptId) {
LambdaQueryWrapper<HirInfectionCase> wrapper = new LambdaQueryWrapper<>();
if (deptId != null) {
wrapper.eq(HirInfectionCase::getEncounterId, deptId);
}
List<HirInfectionCase> cases = infectionCaseService.list(wrapper);
Map<String, Object> result = new HashMap<>();
result.put("totalCases", cases.size());
long confirmed = cases.stream()
.filter(c -> "CONFIRMED".equals(c.getStatus()))
.count();
result.put("confirmedCases", confirmed);
long reported = cases.stream()
.filter(c -> "REPORTED".equals(c.getStatus()))
.count();
result.put("reportedCases", reported);
result.put("infectionRate", cases.isEmpty() ? 0 :
Math.round(confirmed * 1000.0 / cases.size()) / 10.0);
Map<String, Long> byType = cases.stream()
.filter(c -> c.getInfectionType() != null)
.collect(Collectors.groupingBy(HirInfectionCase::getInfectionType, Collectors.counting()));
result.put("byType", byType);
Map<String, Long> bySite = cases.stream()
.filter(c -> c.getInfectionSite() != null)
.collect(Collectors.groupingBy(HirInfectionCase::getInfectionSite, Collectors.counting()));
result.put("bySite", bySite);
return result;
}
@Override
public List<Map<String, Object>> getInfectionTrend(String startDate, String endDate) {
LambdaQueryWrapper<HirInfectionCase> wrapper = new LambdaQueryWrapper<>();

View File

@@ -21,14 +21,6 @@ public class InfectionDetailController {
private final IInfectionDetailAppService infectionDetailAppService;
@Operation(summary = "科室感染率统计")
@PreAuthorize("@ss.hasPermi('infection:infection:list')")
@GetMapping("/rate-by-dept")
public R<Map<String, Object>> getInfectionRateByDept(
@RequestParam(value = "deptId", required = false) Long deptId) {
return R.ok(infectionDetailAppService.getInfectionRateByDept(deptId));
}
@Operation(summary = "感染趋势统计")
@PreAuthorize("@ss.hasPermi('infection:infection:list')")
@GetMapping("/trend")

View File

@@ -4,8 +4,4 @@ import java.util.List;
import java.util.Map;
public interface IMrStatsDetailAppService {
Map<String, Object> getMrStatsByDept(Long deptId);
Map<String, Object> getMrStatsByDoctor(Long doctorId);
}

View File

@@ -1,95 +1,10 @@
package com.healthlink.his.web.mrhomepage.appservice.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.healthlink.his.mrhomepage.domain.MrHomepage;
import com.healthlink.his.mrhomepage.service.IMrHomepageService;
import com.healthlink.his.web.mrhomepage.appservice.IMrStatsDetailAppService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;
@Service
@AllArgsConstructor
public class MrStatsDetailAppServiceImpl implements IMrStatsDetailAppService {
private final IMrHomepageService mrHomepageService;
@Override
public Map<String, Object> getMrStatsByDept(Long deptId) {
LambdaQueryWrapper<MrHomepage> wrapper = new LambdaQueryWrapper<>();
if (deptId != null) {
wrapper.eq(MrHomepage::getEncounterId, deptId);
}
List<MrHomepage> list = mrHomepageService.list(wrapper);
Map<String, Object> result = new HashMap<>();
result.put("totalCount", list.size());
BigDecimal totalCost = list.stream()
.map(MrHomepage::getTotalCost)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
result.put("totalCost", totalCost);
result.put("avgCost", list.isEmpty() ? BigDecimal.ZERO :
totalCost.divide(BigDecimal.valueOf(list.size()), 2, RoundingMode.HALF_UP));
Map<String, Long> byStatus = list.stream()
.collect(Collectors.groupingBy(
h -> h.getQualityStatus() != null ? h.getQualityStatus() : "UNKNOWN",
Collectors.counting()));
result.put("byStatus", byStatus);
Map<String, Long> byDrg = list.stream()
.filter(h -> h.getDrgGroup() != null)
.collect(Collectors.groupingBy(MrHomepage::getDrgGroup, Collectors.counting()));
result.put("byDrg", byDrg);
long totalLos = list.stream()
.mapToInt(h -> h.getLosDays() != null ? h.getLosDays() : 0)
.sum();
result.put("totalLosDays", totalLos);
result.put("avgLosDays", list.isEmpty() ? 0 :
Math.round(totalLos * 10.0 / list.size()) / 10.0);
return result;
}
@Override
public Map<String, Object> getMrStatsByDoctor(Long doctorId) {
LambdaQueryWrapper<MrHomepage> wrapper = new LambdaQueryWrapper<>();
if (doctorId != null) {
wrapper.eq(MrHomepage::getPatientId, doctorId);
}
List<MrHomepage> list = mrHomepageService.list(wrapper);
Map<String, Object> result = new HashMap<>();
result.put("totalCount", list.size());
BigDecimal totalCost = list.stream()
.map(MrHomepage::getTotalCost)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
result.put("totalCost", totalCost);
result.put("avgCost", list.isEmpty() ? BigDecimal.ZERO :
totalCost.divide(BigDecimal.valueOf(list.size()), 2, RoundingMode.HALF_UP));
Map<String, Long> byStatus = list.stream()
.collect(Collectors.groupingBy(
h -> h.getQualityStatus() != null ? h.getQualityStatus() : "UNKNOWN",
Collectors.counting()));
result.put("byStatus", byStatus);
Map<String, Long> byDiagnosis = list.stream()
.filter(h -> h.getPrimaryDiagnosisName() != null)
.collect(Collectors.groupingBy(MrHomepage::getPrimaryDiagnosisName, Collectors.counting()));
result.put("byDiagnosis", byDiagnosis);
return result;
}
}

View File

@@ -1,15 +1,11 @@
package com.healthlink.his.web.mrhomepage.controller;
import com.core.common.core.domain.R;
import com.healthlink.his.web.mrhomepage.appservice.IMrStatsDetailAppService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Tag(name = "病案统计明细")
@RestController
@@ -19,20 +15,4 @@ import java.util.Map;
public class MrStatsDetailController {
private final IMrStatsDetailAppService mrStatsDetailAppService;
@Operation(summary = "科室病案统计")
@PreAuthorize("@ss.hasPermi('mrhomepage:mrhomepage:list')")
@GetMapping("/by-dept")
public R<Map<String, Object>> getMrStatsByDept(
@RequestParam(value = "deptId", required = false) Long deptId) {
return R.ok(mrStatsDetailAppService.getMrStatsByDept(deptId));
}
@Operation(summary = "医生病案统计")
@PreAuthorize("@ss.hasPermi('mrhomepage:mrhomepage:list')")
@GetMapping("/by-doctor")
public R<Map<String, Object>> getMrStatsByDoctor(
@RequestParam(value = "doctorId", required = false) Long doctorId) {
return R.ok(mrStatsDetailAppService.getMrStatsByDoctor(doctorId));
}
}

View File

@@ -184,7 +184,7 @@
LEFT JOIN fin_payment_reconciliation T13
ON T10.id::TEXT = ANY(string_to_array(T13.charge_item_ids,','))
AND T13.delete_flag = '0'
AND T13.status_enum = ${paymentStatus}
AND T13.status_enum = #{paymentStatus}
-- 关联退号记录当状态为退号时通过relation_id关联原支付记录
LEFT JOIN fin_payment_reconciliation T14
ON T13.id = T14.relation_id

View File

@@ -117,7 +117,7 @@
)
</if>
<if test="searchKey != null and searchKey != ''">
AND (t1.name ILIKE '%' || '${searchKey}' || '%' OR t1.py_str ILIKE '%' || '${searchKey}' || '%')
AND (t1.name ILIKE '%' || #{searchKey} || '%' OR t1.py_str ILIKE '%' || #{searchKey} || '%')
</if>
<if test="adviceDefinitionIdParamList != null and !adviceDefinitionIdParamList.isEmpty()">
AND t1.id IN
@@ -190,7 +190,7 @@
WHERE t1.delete_flag = '0'
AND t1.status_enum = #{statusEnum}
<if test="searchKey != null and searchKey != ''">
AND (t1.name ILIKE '%' || '${searchKey}' || '%' OR t1.py_str ILIKE '%' || '${searchKey}' || '%')
AND (t1.name ILIKE '%' || #{searchKey} || '%' OR t1.py_str ILIKE '%' || #{searchKey} || '%')
</if>
<if test="categoryCode != null and categoryCode != ''">
AND t1.category_code = #{categoryCode}
@@ -287,7 +287,7 @@
AND T1.category_code != '手术' AND T1.category_code != '24'
</if>
<if test="searchKey != null and searchKey != ''">
AND (t1.name ILIKE '%' || '${searchKey}' || '%' OR t1.py_str ILIKE '%' || '${searchKey}' || '%')
AND (t1.name ILIKE '%' || #{searchKey} || '%' OR t1.py_str ILIKE '%' || #{searchKey} || '%')
</if>
<if test="categoryCode != null and categoryCode != ''">
AND t1.category_code = #{categoryCode}
@@ -380,7 +380,7 @@
</if>
AND T1.inventory_status_enum = #{status}
AND T1.expiration_date > NOW()
AND T1.item_table IN ( ${SqlCondition} )
AND T1.item_table IN ('med_medication_definition', 'adm_device_definition')
order by T1.expiration_date
</select>

View File

@@ -92,7 +92,7 @@
LEFT JOIN fin_payment_reconciliation T13
ON T10.id::TEXT = ANY(string_to_array(T13.charge_item_ids,','))
AND T13.delete_flag = '0'
AND T13.status_enum = ${paymentStatus}
AND T13.status_enum = #{paymentStatus}
LEFT JOIN adm_invoice AS ai
ON ai.reconciliation_id = T13.id AND ai.delete_flag = '0'
LEFT JOIN order_main AS om ON T1.order_id = om.id AND om.delete_flag = '0'