From 911511d8f55082d761986feb5a280925f416ae2b Mon Sep 17 00:00:00 2001 From: luoweijian <1329394916@qq.com> Date: Tue, 25 Aug 2026 14:50:30 +0800 Subject: [PATCH] =?UTF-8?q?feat(opportunity):=20=E7=A5=A814=20=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E8=A7=86=E5=9B=BE=E6=8E=92=E5=BA=8F=E6=8E=A5?= =?UTF-8?q?=E7=BA=BF=EF=BC=88=E8=A1=A5=E5=BA=95=E7=A8=BF=E5=AE=9A=E4=B9=89?= =?UTF-8?q?2=E6=BC=8F=E9=A1=B9=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 底稿 issues/14 定义2 把「排序字段+方向」列为自定义视图组成部分,实体/DTO 已存 sortField/sortDirection,但上一版查询未接排序(列表恒按 createTime)。补齐: - OpportunitySavedViewFilter.orderByClause(field,direction):字段走同一字段池 白名单→主表列名,方向只认 asc/desc(大小写无关,其余/空→DESC);字段不在池/空→null - ViewQueryImpl.applySavedView 返回排序片段,pageOpportunities 有则 wrapper.last(ORDER BY ...) 替代默认 createTime 倒序,无则回落默认; RECENT 路径为时间序不接排序(时间序优先) - 移除不再直接引用的 SavedView import - 补 3 排序单测(asc/desc默认/未知字段回落) mvn -pl crm-opportunity -am test 147 全绿。 --- .../impl/OpportunitySavedViewFilter.java | 18 ++++++++++ .../query/impl/OpportunityViewQueryImpl.java | 36 ++++++++++++------- .../impl/OpportunitySavedViewFilterTest.java | 24 +++++++++++++ 3 files changed, 65 insertions(+), 13 deletions(-) diff --git a/crm-opportunity/src/main/java/com/crm/opportunity/query/impl/OpportunitySavedViewFilter.java b/crm-opportunity/src/main/java/com/crm/opportunity/query/impl/OpportunitySavedViewFilter.java index a522d23..729859c 100644 --- a/crm-opportunity/src/main/java/com/crm/opportunity/query/impl/OpportunitySavedViewFilter.java +++ b/crm-opportunity/src/main/java/com/crm/opportunity/query/impl/OpportunitySavedViewFilter.java @@ -86,4 +86,22 @@ public class OpportunitySavedViewFilter { case IS_NOT_EMPTY -> wrapper.apply("(" + column + " IS NOT NULL AND " + column + " <> '')"); } } + + /** + * 自定义视图排序翻译(票 14 定义 2:排序字段 + 方向,排序字段同属字段池)。 + *
返回可直接拼入 {@code ORDER BY} 的列片段(如 {@code "owner_user_id DESC"}); + * 字段不在字段池白名单 → {@code null}(调用方回落默认排序)。方向只认 asc/desc + * (大小写无关),其余 / 空 → 默认 DESC。列名走白名单常量,方向只产 ASC/DESC 字面量,无注入面。
+ */ + public String orderByClause(String sortField, String sortDirection) { + if (StrUtil.isBlank(sortField)) { + return null; + } + String column = FIELD_COLUMN.get(sortField); + if (column == null) { + return null; // 排序字段不在字段池 → 回落默认排序 + } + boolean asc = "asc".equalsIgnoreCase(StrUtil.trimToEmpty(sortDirection)); + return column + (asc ? " ASC" : " DESC"); + } } diff --git a/crm-opportunity/src/main/java/com/crm/opportunity/query/impl/OpportunityViewQueryImpl.java b/crm-opportunity/src/main/java/com/crm/opportunity/query/impl/OpportunityViewQueryImpl.java index a56d4e2..ba80576 100644 --- a/crm-opportunity/src/main/java/com/crm/opportunity/query/impl/OpportunityViewQueryImpl.java +++ b/crm-opportunity/src/main/java/com/crm/opportunity/query/impl/OpportunityViewQueryImpl.java @@ -30,7 +30,6 @@ import com.crm.opportunity.mapper.OpportunitySchemeCardMapper; import com.crm.opportunity.mapper.OpportunityStageHistoryMapper; import com.crm.opportunity.mapper.OpportunityViewLogMapper; import com.crm.opportunity.query.OpportunityViewQuery; -import com.crm.preference.domain.dto.SavedView; import com.crm.preference.service.SavedViewService; import com.crm.rule.domain.dto.SysRegionDTO; import com.crm.rule.domain.entity.OpportunityStageNode; @@ -101,8 +100,13 @@ public class OpportunityViewQueryImpl implements OpportunityViewQuery { LambdaQueryWrapper视图不存在(已删 / 非本人)→ 无额外条件(等价写回未选自定义视图)。 - * 排序(sortField/sortDirection)本期不入库级排序(列表默认按 createTime),留后续实现。
+ * 自定义视图叠加(票 14):{@code param.savedViewId} 非空时,读当前用户 + * {@code opportunity.sales} scope 下该视图,把检索条件翻译后 AND 叠在当前数据集之上, + * 并返回排序列片段供调用方替代默认排序。 + *视图不存在(已删 / 非本人)或 savedViewId 空 → 返回 {@code null}(无额外条件且回落默认排序)。
+ * + * @return 自定义视图排序列片段(如 {@code "owner_user_id DESC"});无排序 / 排序字段不在字段池 → {@code null} */ - private void applySavedView(LambdaQueryWrapper