From 03c3e3cfc1262e26a218a4b8340c0a53ca3065c6 Mon Sep 17 00:00:00 2001
From: zhou zhou <3272660260@qq.com>
Date: 星期四, 09 四月 2026 13:37:08 +0800
Subject: [PATCH] #logo和高危修复

---
 rsf-server/src/main/java/com/vincent/rsf/server/system/controller/BaseController.java |  234 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 233 insertions(+), 1 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 bada2f7..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,21 +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();
@@ -41,7 +53,42 @@
         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");
+            meta.keySet().forEach(key -> {
+                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 {
             t = clz.getDeclaredConstructor().newInstance();
@@ -69,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