diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/warehouse/StockInfoController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/warehouse/StockInfoController.java index c4e65bb..bc91555 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/warehouse/StockInfoController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/warehouse/StockInfoController.java @@ -1,5 +1,6 @@ package com.ruoyi.web.controller.warehouse; +import java.util.Collections; import java.util.List; import jakarta.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; @@ -11,10 +12,14 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.constant.HttpStatus; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.page.PageDomain; import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.core.page.TableSupport; import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.warehouse.domain.OutRecord; import com.ruoyi.warehouse.domain.StockInfo; @@ -31,10 +36,31 @@ public class StockInfoController extends BaseController @GetMapping("/list") public TableDataInfo list(StockInfo stockInfo) { + if (StringUtils.isNotBlank(stockInfo.getProductName())) + { + return getKeywordDataTable(stockInfoService.selectStockInfoList(stockInfo)); + } startPage(); return getDataTable(stockInfoService.selectStockInfoList(stockInfo)); } + private TableDataInfo getKeywordDataTable(List list) + { + PageDomain pageDomain = TableSupport.buildPageRequest(); + int pageNum = pageDomain.getPageNum() == null || pageDomain.getPageNum() < 1 ? 1 : pageDomain.getPageNum(); + int pageSize = pageDomain.getPageSize() == null || pageDomain.getPageSize() < 1 ? 10 : pageDomain.getPageSize(); + int total = list == null ? 0 : list.size(); + int fromIndex = Math.min((pageNum - 1) * pageSize, total); + int toIndex = Math.min(fromIndex + pageSize, total); + + TableDataInfo rspData = new TableDataInfo(); + rspData.setCode(HttpStatus.SUCCESS); + rspData.setMsg("查询成功"); + rspData.setTotal(total); + rspData.setRows(total == 0 ? Collections.emptyList() : list.subList(fromIndex, toIndex)); + return rspData; + } + @PreAuthorize("@ss.hasPermi('warehouse:stock:export')") @Log(title = "库存信息", businessType = BusinessType.EXPORT) @PostMapping("/export") diff --git a/ruoyi-system/src/main/java/com/ruoyi/warehouse/service/impl/StockInfoServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/warehouse/service/impl/StockInfoServiceImpl.java index 7442329..239c95a 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/warehouse/service/impl/StockInfoServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/warehouse/service/impl/StockInfoServiceImpl.java @@ -1,9 +1,12 @@ package com.ruoyi.warehouse.service.impl; +import java.util.ArrayList; +import java.util.LinkedHashSet; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.StringUtils; import com.ruoyi.warehouse.domain.OutRecord; import com.ruoyi.warehouse.domain.StockInfo; import com.ruoyi.warehouse.mapper.StockInfoMapper; @@ -13,6 +16,8 @@ import com.ruoyi.warehouse.service.IStockInfoService; @Service public class StockInfoServiceImpl implements IStockInfoService { + private static final int MAX_KEYWORD_TOKEN_COUNT = 5; + @Autowired private StockInfoMapper stockInfoMapper; @@ -22,7 +27,121 @@ public class StockInfoServiceImpl implements IStockInfoService @Override public List selectStockInfoList(StockInfo stockInfo) { - return stockInfoMapper.selectStockInfoList(stockInfo); + List tokens = parseKeywordTokens(stockInfo); + List list = stockInfoMapper.selectStockInfoList(stockInfo); + if (tokens.isEmpty()) + { + return list; + } + List scoredList = new ArrayList<>(); + for (StockInfo item : list) + { + int score = scoreStock(item, tokens); + if (score > 0) + { + scoredList.add(new ScoredStock(item, score)); + } + } + scoredList.sort((left, right) -> { + int scoreCompare = Integer.compare(right.score, left.score); + if (scoreCompare != 0) + { + return scoreCompare; + } + long leftId = left.stock.getId() == null ? 0L : left.stock.getId(); + long rightId = right.stock.getId() == null ? 0L : right.stock.getId(); + return Long.compare(rightId, leftId); + }); + List result = new ArrayList<>(scoredList.size()); + for (ScoredStock item : scoredList) + { + result.add(item.stock); + } + return result; + } + + private List parseKeywordTokens(StockInfo stockInfo) + { + if (stockInfo == null || StringUtils.isBlank(stockInfo.getProductName())) + { + return new ArrayList<>(); + } + LinkedHashSet tokens = new LinkedHashSet<>(); + String keyword = stockInfo.getProductName().trim().toLowerCase(); + for (String item : keyword.split("[\\s,,;;、]+")) + { + if (StringUtils.isNotBlank(item)) + { + tokens.add(item.trim()); + } + if (tokens.size() >= MAX_KEYWORD_TOKEN_COUNT) + { + break; + } + } + if (tokens.isEmpty()) + { + return new ArrayList<>(); + } + stockInfo.getParams().put("keywordTokens", new ArrayList<>(tokens)); + return new ArrayList<>(tokens); + } + + private int scoreStock(StockInfo stock, List tokens) + { + int totalScore = 0; + for (String token : tokens) + { + int tokenScore = 0; + tokenScore += scoreField(stock.getProductName(), token, 120, 90, 60); + tokenScore += scoreField(stock.getSpec(), token, 90, 70, 45); + tokenScore += scoreField(stock.getBrand(), token, 80, 60, 40); + tokenScore += scoreField(stock.getCategory(), token, 70, 50, 35); + tokenScore += scoreField(stock.getAreaName(), token, 65, 45, 30); + tokenScore += scoreField(stock.getUnit(), token, 35, 0, 20); + tokenScore += scoreField(stock.getProductCode(), token, 0, 0, 10); + tokenScore += scoreField(stock.getAreaCode(), token, 0, 0, 10); + if (tokenScore <= 0) + { + return 0; + } + totalScore += tokenScore; + } + return totalScore; + } + + private int scoreField(String value, String token, int exactScore, int prefixScore, int containsScore) + { + if (StringUtils.isBlank(value) || StringUtils.isBlank(token)) + { + return 0; + } + String lowerValue = value.toLowerCase(); + if (exactScore > 0 && lowerValue.equals(token)) + { + return exactScore; + } + if (prefixScore > 0 && lowerValue.startsWith(token)) + { + return prefixScore; + } + if (containsScore > 0 && lowerValue.contains(token)) + { + return containsScore; + } + return 0; + } + + private static class ScoredStock + { + private final StockInfo stock; + private final int score; + + private ScoredStock(StockInfo stock, int score) + { + this.stock = stock; + this.score = score; + } } @Override diff --git a/ruoyi-system/src/main/resources/mapper/warehouse/StockInfoMapper.xml b/ruoyi-system/src/main/resources/mapper/warehouse/StockInfoMapper.xml index bddc888..bb7843d 100644 --- a/ruoyi-system/src/main/resources/mapper/warehouse/StockInfoMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/warehouse/StockInfoMapper.xml @@ -33,8 +33,8 @@ and si.area_id = #{areaId} and si.product_id = #{productId} and wa.area_name like concat('%', #{areaName}, '%') - - and lower(concat_ws(' ', pi.product_name, pi.brand, pi.category, pi.spec, pi.unit)) + + and lower(concat_ws(' ', pi.product_name, pi.brand, pi.category, pi.spec, pi.unit, wa.area_name)) like concat('%', lower(#{productName}), '%') diff --git a/ruoyi-ui/src/views/mobile/index.vue b/ruoyi-ui/src/views/mobile/index.vue index 972d632..a6728a5 100644 --- a/ruoyi-ui/src/views/mobile/index.vue +++ b/ruoyi-ui/src/views/mobile/index.vue @@ -118,7 +118,7 @@ - + 搜索 diff --git a/ruoyi-ui/src/views/warehouse/stock/index.vue b/ruoyi-ui/src/views/warehouse/stock/index.vue index 7ef577b..3fcf732 100644 --- a/ruoyi-ui/src/views/warehouse/stock/index.vue +++ b/ruoyi-ui/src/views/warehouse/stock/index.vue @@ -6,8 +6,8 @@ - - + + 搜索