From 523365960513f297024a419f94b2b42eccd9456f Mon Sep 17 00:00:00 2001
From: zhou zhou <3272660260@qq.com>
Date: 星期四, 09 四月 2026 11:21:41 +0800
Subject: [PATCH] #
---
rsf-server/src/main/java/com/vincent/rsf/server/system/controller/BaseController.java | 228 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 225 insertions(+), 3 deletions(-)
diff --git a/rsf-server/src/main/java/com/vincent/rsf/server/system/controller/BaseController.java b/rsf-server/src/main/java/com/vincent/rsf/server/system/controller/BaseController.java
index 972a3f9..1511caf 100644
--- a/rsf-server/src/main/java/com/vincent/rsf/server/system/controller/BaseController.java
+++ b/rsf-server/src/main/java/com/vincent/rsf/server/system/controller/BaseController.java
@@ -1,24 +1,33 @@
package com.vincent.rsf.server.system.controller;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.vincent.rsf.common.utils.Utils;
import com.vincent.rsf.framework.common.Cools;
import com.vincent.rsf.server.common.domain.BaseParam;
+import com.vincent.rsf.server.common.domain.CursorPageParam;
+import com.vincent.rsf.server.common.domain.CursorPageResult;
+import com.vincent.rsf.server.common.domain.PageParam;
import com.vincent.rsf.server.system.entity.User;
import org.springframework.security.core.Authentication;
+import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.function.Consumer;
/**
* Created by vincent on 1/30/2024
*/
public class BaseController {
-
-
-
public User getLoginUser() {
try {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
@@ -44,6 +53,26 @@
return loginUser == null ? null : loginUser.getTenantId();
}
+ public boolean hasAuthority(String authority) {
+ if (authority == null || authority.trim().isEmpty()) {
+ return false;
+ }
+ try {
+ Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ if (authentication == null || authentication.getAuthorities() == null) {
+ return false;
+ }
+ for (GrantedAuthority grantedAuthority : authentication.getAuthorities()) {
+ if (grantedAuthority != null && authority.equals(grantedAuthority.getAuthority())) {
+ return true;
+ }
+ }
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ }
+ return false;
+ }
+
public <T extends BaseParam> T buildParam(Map<String, Object> map, Class<T> clz) {
if (!Objects.isNull(map.get("meta"))) {
Map<String, Object> meta = (Map<String, Object>) map.get("meta");
@@ -51,6 +80,14 @@
map.put(key, meta.get(key));
});
map.remove("meta");
+ }
+ // 绉婚櫎绛涢�夋潯浠堕噷闈㈢殑 $
+ for (String key : map.keySet()) {
+ Object value = map.get(key);
+ if (key.equals("orderBy")) {
+ String newValue = value.toString().replace("$", "");
+ map.replace("orderBy", value, newValue);
+ }
}
T t = null;
try {
@@ -79,4 +116,189 @@
return true;
}
+ /**
+ * 閫氱敤娓告爣鍒嗛〉瀹炵幇銆�
+ *
+ * <p>杩欎釜鏂规硶鐨勭洰鏍囦笉鏄浛浠f墍鏈夊垎椤碉紝鑰屾槸鎶娾�滃崟瀛楁銆佸�掑簭銆佸悜鍚庣炕椤碘�濈殑娓告爣鍒嗛〉
+ * 鏀舵暃鎴愪竴濂楃粺涓�瀹炵幇锛岄伩鍏嶅悇涓� controller 閲嶅鍐欎笅闈㈣繖浜涙牱鏉块�昏緫锛�</p>
+ * <ul>
+ * <li>buildParam</li>
+ * <li>蹇界暐鍓嶇浼犲叆鐨� orderBy</li>
+ * <li>buildWrapper(true) 鏋勫缓閫氱敤绛涢��</li>
+ * <li>cursor 鏉′欢</li>
+ * <li>鎸夊浐瀹氬瓧娈靛�掑簭</li>
+ * <li>澶氭煡涓�鏉″垽鏂� hasNext</li>
+ * <li>鎴柇缁撴灉骞剁敓鎴� nextCursor</li>
+ * </ul>
+ *
+ * <p>閫傜敤鍓嶆彁锛�</p>
+ * <ul>
+ * <li>娓告爣瀛楁鏄崟涓�瀛楁</li>
+ * <li>娓告爣瀛楁鐨勫�肩ǔ瀹氥�佸彲姣旇緝锛屽苟涓旇兘鏄犲皠鎴� Long</li>
+ * <li>鍒嗛〉鏂瑰悜鍥哄畾涓衡�滄寜璇ュ瓧娈靛�掑簭锛屽悜鏇村皬鐨勫�肩炕椤碘��</li>
+ * </ul>
+ *
+ * <p>鍙傛暟璇存槑锛�</p>
+ * <ul>
+ * <li>{@code map}锛氬師濮嬭姹傚弬鏁�</li>
+ * <li>{@code paramClass}锛氭父鏍囧弬鏁扮被鍨嬶紝閫氬父浼� {@link CursorPageParam}</li>
+ * <li>{@code entityClass}锛氬疄浣撶被锛岀敤浜� PageParam 鏉′欢鏋勫缓鍜� condition 妯$硦鏌ヨ</li>
+ * <li>{@code service}锛歁yBatis-Plus 鐨� IService锛岃礋璐f墽琛� page 鏌ヨ</li>
+ * <li>{@code cursorField}锛氬疄浣撳瓧娈靛悕锛屼笉鏄暟鎹簱鍒楀悕锛屼緥濡備紶 {@code id}</li>
+ * <li>{@code defaultPageSize}锛氬綋鍓嶆帴鍙g殑榛樿鍒嗛〉澶у皬</li>
+ * <li>{@code wrapperConsumer}锛氬彲閫夌殑棰濆 where 鏉′欢鎵╁睍閽╁瓙</li>
+ * <li>{@code recordsConsumer}锛氬彲閫夌殑缁撴灉鍚庡鐞嗛挬瀛愶紝渚嬪琛ュ厖 createBy$/updateBy$</li>
+ * </ul>
+ */
+ protected <T, U extends CursorPageParam> CursorPageResult<T> cursorPage(
+ Map<String, Object> map,
+ Class<U> paramClass,
+ Class<T> entityClass,
+ IService<T> service,
+ String cursorField,
+ int defaultPageSize,
+ Consumer<QueryWrapper<T>> wrapperConsumer,
+ Consumer<List<T>> recordsConsumer
+ ) {
+ // 鍏佽 controller 浼� null锛屽唴閮ㄧ粺涓�鍏滃簳鎴愮┖ map锛�
+ // 杩欐牱 buildParam 涓嶉渶瑕佹瘡涓皟鐢ㄦ柟鑷繁鍏堝垽绌恒��
+ U baseParam = buildParam(map == null ? new HashMap<>() : map, paramClass);
+
+ // 娓告爣鍒嗛〉涓嶅厑璁稿鎴风鑷畾涔夋帓搴忥紝
+ // 鍚﹀垯鈥滀笂涓�椤垫渶鍚庝竴鏉′綔涓轰笅涓�椤垫父鏍団�濈殑鍓嶆彁浼氳鐮村潖銆�
+ baseParam.setOrderBy(null);
+
+ // pageSize 鍏佽浠庤姹傞噷甯﹀叆锛屼絾闈炴硶鍊硷紙null銆�0銆佽礋鏁帮級缁熶竴鍥為��鍒版帴鍙i粯璁ゅ�笺��
+ int pageSize = resolveCursorPageSize(baseParam.getPageSize(), defaultPageSize);
+
+ // controller 浼犵殑鏄疄浣撳瓧娈靛悕锛屼緥濡� "id" / "poId"锛�
+ // 杩欓噷缁熶竴杞垚鏁版嵁搴撳垪鍚嶅苟琛ュ弽寮曞彿锛岄伩鍏嶆瘡涓笟鍔¤嚜宸辨墜鍐� SQL 鐗囨銆�
+ String cursorColumn = resolveCursorColumn(cursorField);
+
+ // 鍏堝鐢ㄧ郴缁熺幇鏈夌殑 PageParam + buildWrapper(true) 鏈哄埗锛�
+ // 淇濈暀鍘熸潵鐨勬潯浠惰В鏋愩�佹椂闂磋寖鍥淬�乧ondition 妯$硦鎼滅储绛夎兘鍔涖��
+ PageParam<T, U> pageParam = new PageParam<>(baseParam, entityClass);
+ QueryWrapper<T> wrapper = pageParam.buildWrapper(true);
+
+ // 缁欎笟鍔¢鐣欓澶� where 鏉′欢鐨勬墿灞曠偣锛�
+ // 濡傛灉鏌愪釜鎺ュ彛闄や簡閫氱敤绛涢�夊锛岃繕瑕佹嫾鎺ラ澶栭檺鍒讹紝鍙互鍦ㄨ繖閲岃ˉ銆�
+ if (wrapperConsumer != null) {
+ wrapperConsumer.accept(wrapper);
+ }
+
+ // 娓告爣鍒嗛〉鐨勬牳蹇冩潯浠讹細
+ // 褰撳墠绾﹀畾鏄�滄寜 cursorField 鍊掑簭鏌ョ湅鏇存棫鐨勬暟鎹�濓紝鎵�浠ユ潯浠跺浐瀹氫负 < cursor銆�
+ if (baseParam.getCursor() != null) {
+ wrapper.lt(cursorColumn, baseParam.getCursor());
+ }
+
+ // 寮哄埗鎸夋父鏍囧瓧娈靛�掑簭鎺掑簭锛屼繚璇佹瘡涓�椤电殑鏁版嵁椤哄簭绋冲畾銆�
+ wrapper.orderByDesc(cursorColumn);
+
+ // 澶氭煡涓�鏉℃槸娓告爣鍒嗛〉鍒ゆ柇 hasNext 鐨勫父瑙佸仛娉曪細
+ // 瀹為檯瑕� 20 鏉★紝灏辨煡 21 鏉★紱澶氬嚭鏉ラ偅涓�鏉″彧鐢ㄦ潵鍒ゆ柇鏄惁杩樻湁涓嬩竴椤点��
+ Page<T> queryPage = new Page<>(1L, pageSize + 1L, false);
+ List<T> records = service.page(queryPage, wrapper).getRecords();
+ List<T> pageRecords = Cools.isEmpty(records) ? new ArrayList<>() : new ArrayList<>(records);
+
+ // 濡傛灉鏌ュ嚭鏉ョ殑鏁伴噺澶т簬 pageSize锛岃鏄庤嚦灏戣繕鏈変笅涓�椤点��
+ boolean hasNext = pageRecords.size() > pageSize;
+ if (hasNext) {
+ // 鍙妸鐪熸闇�瑕佽繑鍥炵粰鍓嶇鐨� pageSize 鏉℃暟鎹暀鍦ㄥ綋鍓嶉〉銆�
+ pageRecords = new ArrayList<>(pageRecords.subList(0, pageSize));
+ }
+
+ // 缁欎笟鍔′晶涓�涓�滅粨鏋滃嚭搴撳墠澶勭悊鈥濈殑鏈轰細銆�
+ // 鍏稿瀷鍦烘櫙鏄壒閲忚ˉ鍏呯敤鎴峰悕銆佸瓧鍏告枃鏈�佺紦瀛樺瓧娈电瓑锛�
+ // 杩欐牱鍏叡鍒嗛〉閫昏緫涓嶅叧蹇冧笟鍔$粏鑺傦紝浣嗕笟鍔′篃涓嶉渶瑕佸洖鍒� controller 鑷繁閲嶅啓鍒嗛〉銆�
+ if (recordsConsumer != null && !Cools.isEmpty(pageRecords)) {
+ recordsConsumer.accept(pageRecords);
+ }
+
+ CursorPageResult<T> result = new CursorPageResult<>();
+ result.setRecords(pageRecords);
+ result.setPageSize(pageSize);
+ result.setHasNext(hasNext);
+ // nextCursor 鍙湁鍦ㄨ繕鏈変笅涓�椤垫椂鎵嶆湁鎰忎箟锛�
+ // 绾﹀畾鍙栤�滃綋鍓嶉〉鏈�鍚庝竴鏉¤褰曗�濈殑娓告爣瀛楁鍊笺��
+ result.setNextCursor(hasNext ? extractCursorValue(pageRecords, cursorField) : null);
+ return result;
+ }
+
+ /**
+ * 缁熶竴瑙f瀽褰撳墠鎺ュ彛瀹為檯浣跨敤鐨� pageSize銆�
+ *
+ * <p>鍙鍓嶇娌′紶銆佷紶浜� 0銆佹垨鑰呬紶浜嗚礋鏁帮紝灏卞洖閫�鍒� controller 浼犲叆鐨勯粯璁ゅ�笺��</p>
+ */
+ private int resolveCursorPageSize(Integer pageSize, int defaultPageSize) {
+ if (pageSize == null || pageSize <= 0) {
+ return defaultPageSize;
+ }
+ return pageSize;
+ }
+
+ /**
+ * 鎶婂疄浣撳瓧娈靛悕杞崲鎴愭暟鎹簱鍒楀悕銆�
+ *
+ * <p>渚嬪锛�</p>
+ * <ul>
+ * <li>{@code id -> `id`}</li>
+ * <li>{@code poId -> `po_id`}</li>
+ * </ul>
+ *
+ * <p>杩欐牱 controller 璋冪敤鏃跺彧闇�瑕佸叧蹇� Java 瀛楁鍚嶏紝涓嶉渶瑕佽嚜宸辨嫾 SQL銆�</p>
+ */
+ private String resolveCursorColumn(String cursorField) {
+ return "`" + Utils.toSymbolCase(cursorField, '_') + "`";
+ }
+
+ /**
+ * 浠庡綋鍓嶉〉鏈�鍚庝竴鏉¤褰曚腑鎻愬彇 nextCursor銆�
+ *
+ * <p>杩欓噷浣跨敤鍙嶅皠鑰屼笉鏄澶栧畾涔夋帴鍙o紝鐩殑鏄檷浣庢帴鍏ユ垚鏈細
+ * 鍙瀹炰綋閲屽瓨鍦ㄥ悓鍚嶅瓧娈碉紝灏辫兘鐩存帴澶嶇敤閫氱敤鏂规硶銆�</p>
+ *
+ * <p>鏀寔鐨勫瓧娈靛�肩被鍨嬶細</p>
+ * <ul>
+ * <li>{@link Long}</li>
+ * <li>鍏朵粬 {@link Number}</li>
+ * <li>鍙浆鎴� Long 鐨勫瓧绗︿覆</li>
+ * </ul>
+ *
+ * <p>濡傛灉瀛楁涓嶅瓨鍦ㄣ�佷负绌恒�佹垨鏃犳硶杞垚 Long锛屽垯杩斿洖 null銆�</p>
+ */
+ private <T> Long extractCursorValue(List<T> records, String cursorField) {
+ if (Cools.isEmpty(records)) {
+ return null;
+ }
+ T lastRecord = records.get(records.size() - 1);
+ if (lastRecord == null || Cools.isEmpty(cursorField)) {
+ return null;
+ }
+ Field field = Cools.getField(lastRecord.getClass(), cursorField);
+ if (field == null) {
+ return null;
+ }
+ boolean accessible = field.isAccessible();
+ try {
+ field.setAccessible(true);
+ Object value = field.get(lastRecord);
+ if (value instanceof Long) {
+ return (Long) value;
+ }
+ if (value instanceof Number) {
+ return ((Number) value).longValue();
+ }
+ if (value instanceof String && !((String) value).trim().isEmpty()) {
+ return Long.parseLong(((String) value).trim());
+ }
+ } catch (IllegalAccessException | NumberFormatException ignored) {
+ return null;
+ } finally {
+ field.setAccessible(accessible);
+ }
+ return null;
+ }
+
}
+
--
Gitblit v1.9.1