diff --git a/src/main/java/com/spring/modules/lab/service/impl/LabServiceImpl.java b/src/main/java/com/spring/modules/lab/service/impl/LabServiceImpl.java index a88d20ab..eb01deb6 100644 --- a/src/main/java/com/spring/modules/lab/service/impl/LabServiceImpl.java +++ b/src/main/java/com/spring/modules/lab/service/impl/LabServiceImpl.java @@ -3,6 +3,8 @@ package com.spring.modules.lab.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.metadata.OrderItem; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.spring.common.utils.Constant; import com.spring.common.utils.DateUtils; @@ -49,6 +51,8 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import static com.spring.modules.base.utils.CommonUtils.getPropertyValue; @@ -57,6 +61,9 @@ public class LabServiceImpl extends ServiceImpl implements private static final String LAB_PROPERTY_TYPE = "LAB"; private static final String LAB_TEST_LAB_DICT_TYPE = "lab_test_lab"; private static final String LAB_TEST_LAB_DICT_SITE = "41"; + private static final Pattern ORDER_COLUMN_PATTERN = Pattern.compile("^[A-Za-z0-9_.]+$"); + private static final Pattern TESTER_EQUAL_PATTERN = Pattern.compile("(?i)\\ba\\.tester\\b\\s*=\\s*'([^']*)'"); + private static final Pattern TESTER_LIKE_PATTERN = Pattern.compile("(?i)\\ba\\.tester\\b\\s+like\\s*'([^']*)'"); @Autowired private SysUserDao sysUserDao; @@ -99,6 +106,11 @@ public class LabServiceImpl extends ServiceImpl implements params.put("referenceNo", trimToNull((String) params.get("referenceNo"))); params.put("applicant", trimToNull((String) params.get("applicant"))); params.put("currentApprover", trimToNull((String) params.get("currentApprover"))); + params.put("tester", trimToNull((String) params.get("tester"))); + params.put("testerLike", buildTesterLikeParam((String) params.get("tester"))); + // 主信息列表固定按序列号倒排,避免被前端排序参数覆盖 + params.put(Constant.ORDER_FIELD, "reference_no"); + params.put(Constant.ORDER, "desc"); IPage page = this.baseMapper.queryPageWithNames( new Query().getPage(params, "reference_no", false), @@ -119,16 +131,18 @@ public class LabServiceImpl extends ServiceImpl implements } else { whereClause = StringUtils.defaultString(whereClause).trim(); } + whereClause = normalizeTesterSearchWhereClause(whereClause); orderClause = StringUtils.defaultString(orderClause).trim(); Map params = new HashMap<>(); params.put("menuId", data.getMenuId()); params.put("userName", data.getUserName()); params.put("whereClause", whereClause); - params.put("orderClause", orderClause); + Page pageReq = new Page<>(data.getNo(), data.getSize()); + applyPageOrder(pageReq, orderClause); IPage page = this.baseMapper.queryPageWithNamesAny( - new com.baomidou.mybatisplus.extension.plugins.pagination.Page(data.getNo(), data.getSize()), + pageReq, params ); return new PageUtils(page); @@ -617,6 +631,98 @@ public class LabServiceImpl extends ServiceImpl implements return value; } + private String buildTesterLikeParam(String rawValue) { + String value = trimToNull(rawValue); + if (value == null) { + return null; + } + return value; + } + + private String normalizeTesterSearchWhereClause(String whereClause) { + String normalizedWhereClause = StringUtils.trimToEmpty(whereClause); + if (StringUtils.isBlank(normalizedWhereClause)) { + return normalizedWhereClause; + } + normalizedWhereClause = replaceTesterConditionToTokenLike(normalizedWhereClause, TESTER_LIKE_PATTERN); + normalizedWhereClause = replaceTesterConditionToTokenLike(normalizedWhereClause, TESTER_EQUAL_PATTERN); + return normalizedWhereClause; + } + + private String replaceTesterConditionToTokenLike(String whereClause, Pattern conditionPattern) { + if (StringUtils.isBlank(whereClause) || conditionPattern == null) { + return StringUtils.defaultString(whereClause); + } + Matcher matcher = conditionPattern.matcher(whereClause); + StringBuffer buffer = new StringBuffer(); + boolean replaced = false; + while (matcher.find()) { + String testerValue = StringUtils.trimToEmpty(matcher.group(1)); + if (StringUtils.isBlank(testerValue)) { + matcher.appendReplacement(buffer, Matcher.quoteReplacement("1 = 0")); + replaced = true; + continue; + } + String escapedTesterValue = testerValue.replace("'", "''"); + String replacement = "(';' + isnull(replace(a.tester, ',', ';'), '') + ';') like ('%;" + escapedTesterValue + ";%')"; + matcher.appendReplacement(buffer, Matcher.quoteReplacement(replacement)); + replaced = true; + } + if (!replaced) { + return whereClause; + } + matcher.appendTail(buffer); + return buffer.toString(); + } + + private void applyPageOrder(Page page, String orderClause) { + if (page == null) { + return; + } + String normalizedOrderClause = StringUtils.trimToEmpty(orderClause); + if (StringUtils.startsWithIgnoreCase(normalizedOrderClause, "order by")) { + normalizedOrderClause = StringUtils.trimToEmpty(normalizedOrderClause.substring(8)); + } + if (StringUtils.isBlank(normalizedOrderClause)) { + page.addOrder(OrderItem.desc("reference_no")); + return; + } + boolean hasValidOrder = false; + String[] orderItems = normalizedOrderClause.split(","); + for (String orderItem : orderItems) { + String singleOrder = StringUtils.trimToEmpty(orderItem); + if (StringUtils.isBlank(singleOrder)) { + continue; + } + String orderDirection = "DESC"; + String orderColumn = singleOrder; + int lastSpaceIndex = singleOrder.lastIndexOf(" "); + if (lastSpaceIndex > 0) { + String maybeDirection = StringUtils.trimToEmpty(singleOrder.substring(lastSpaceIndex + 1)); + if ("ASC".equalsIgnoreCase(maybeDirection) || "DESC".equalsIgnoreCase(maybeDirection)) { + orderDirection = maybeDirection.toUpperCase(); + orderColumn = StringUtils.trimToEmpty(singleOrder.substring(0, lastSpaceIndex)); + } + } + if (!isSafeOrderColumn(orderColumn)) { + continue; + } + if ("ASC".equalsIgnoreCase(orderDirection)) { + page.addOrder(OrderItem.asc(orderColumn)); + } else { + page.addOrder(OrderItem.desc(orderColumn)); + } + hasValidOrder = true; + } + if (!hasValidOrder) { + page.addOrder(OrderItem.desc("reference_no")); + } + } + + private boolean isSafeOrderColumn(String orderColumn) { + return StringUtils.isNotBlank(orderColumn) && ORDER_COLUMN_PATTERN.matcher(orderColumn).matches(); + } + private String queryLabTestLabLabelByValue(String dictValue) { List dictRows = dictDataService.lambdaQuery() .eq(DictData::getSite, LAB_TEST_LAB_DICT_SITE) diff --git a/src/main/resources/mapper/lab/LabMapper.xml b/src/main/resources/mapper/lab/LabMapper.xml index dc5430b6..5bf212fc 100644 --- a/src/main/resources/mapper/lab/LabMapper.xml +++ b/src/main/resources/mapper/lab/LabMapper.xml @@ -144,6 +144,9 @@ and a.applicant like #{params.applicant} + + and (';' + isnull(replace(a.tester, ',', ';'), '') + ';') like ('%;' + #{params.testerLike} + ';%') +