diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaProjectServiceImpl.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaProjectServiceImpl.java index cbc60bf..1e2e1cf 100644 --- a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaProjectServiceImpl.java +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/SysOaProjectServiceImpl.java @@ -90,23 +90,29 @@ public class SysOaProjectServiceImpl implements ISysOaProjectService { wrapper.ge(StringUtils.isNotBlank(beginTimeStart), "p.begin_time", beginTimeStart); wrapper.le(StringUtils.isNotBlank(beginTimeEnd), "p.begin_time", beginTimeEnd); - // 3. 构建HAVING子句, 用于筛选计算后的盈亏值 - StringBuilder havingClause = new StringBuilder(); + // 先把 profit_loss 的 CASE 表达式完整地组装成一个字符串 + String profitLossExpr = "(" + + "CASE " + + " WHEN p.funds IS NOT NULL AND p.funds > 0 THEN " + + " CASE WHEN p.remark LIKE '%美元%' OR p.remark LIKE '%美金%' " + + " THEN p.funds * " + currentExchangeRate + + " ELSE p.funds END " + + " ELSE COALESCE(finance_details.total_income, 0) " + + "END " + + " - COALESCE(finance_details.total_expenditure, 0)" + + ")"; + +// 不用 wrapper.having(...) if ("profit".equals(profitType)) { - havingClause.append("profit_loss > 0"); + wrapper.apply(profitLossExpr + " > 0"); } else if ("loss".equals(profitType)) { - havingClause.append("profit_loss < 0"); + wrapper.apply(profitLossExpr + " < 0"); } if (minProfitLoss != null) { - if (havingClause.length() > 0) havingClause.append(" AND "); - havingClause.append("profit_loss >= ").append(minProfitLoss); + wrapper.apply(profitLossExpr + " >= {0}", minProfitLoss); } if (maxProfitLoss != null) { - if (havingClause.length() > 0) havingClause.append(" AND "); - havingClause.append("profit_loss <= ").append(maxProfitLoss); - } - if (havingClause.length() > 0) { - wrapper.having(havingClause.toString()); + wrapper.apply(profitLossExpr + " <= {0}", maxProfitLoss); } // 4. 构建分页对象 (排序由PageQuery自动处理)