From f68d79d0ff6658795c19c2fd473fab9ff6f0640d Mon Sep 17 00:00:00 2001
From: zss <zss@example.com>
Date: 星期六, 14 三月 2026 13:53:12 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev_宁夏_中盛建材' into dev_宁夏_中盛建材

---
 src/main/java/com/ruoyi/framework/util/AliDingUtils.java |  173 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 173 insertions(+), 0 deletions(-)

diff --git a/src/main/java/com/ruoyi/framework/util/AliDingUtils.java b/src/main/java/com/ruoyi/framework/util/AliDingUtils.java
new file mode 100644
index 0000000..bd1eea7
--- /dev/null
+++ b/src/main/java/com/ruoyi/framework/util/AliDingUtils.java
@@ -0,0 +1,173 @@
+package com.ruoyi.framework.util;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
+import com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.http.HttpUtils;
+import com.ruoyi.framework.config.AliDingConfig;
+import lombok.extern.slf4j.Slf4j;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.nio.charset.StandardCharsets;
+import java.time.LocalDateTime;
+import java.time.OffsetDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
+
+/**
+ * <br>
+ * 鏍规嵁瀹滄惌琛ㄥ崟 ID 鑾峰彇鏁版嵁
+ * </br>
+ *
+ * @author deslrey
+ * @version 1.0
+ * @since 2026/03/14 11:11
+ */
+@Slf4j
+public class AliDingUtils {
+
+
+    /**
+     * 鏍规嵁琛ㄥ崟 ID 鑾峰彇瀹滄惌鏁版嵁
+     *
+     * @param aliDingConfig   閽夐拤瀹滄惌鎺ュ彛閰嶇疆
+     * @param formUuid        鑾峰彇鏁版嵁鐨勮〃鍗旾D
+     * @param searchFieldJson 闇�瑕佹惡甯︾殑鏌ヨ鏉′欢
+     * @param service         鑾峰彇鏈�杩戣〃鍗曟洿鏂扮殑鏃ユ湡Service
+     * @param timeField       琛ㄥ崟淇敼鏃ユ湡
+     * @param <T>             瀹炰綋绫�
+     * @return 瀵瑰簲琛ㄥ崟鐨勬暟鎹�
+     */
+    public static <T> JSONArray getFormDataList(AliDingConfig aliDingConfig, String formUuid, String searchFieldJson, IService<T> service, SFunction<T, ?> timeField) {
+        //  鑾峰彇 accessToken
+        String accessToken = getAccessToken(aliDingConfig);
+        //  鑾峰彇鏈�鍚庡悓姝ユ椂闂�
+        LocalDateTime lastSyncTime = getLastSyncTime(service, timeField);
+        log.info("寮�濮嬪悓姝ユ暟鎹紝鏈湴鏈�鍚庝慨鏀规椂闂�: {}", lastSyncTime);
+
+        JSONArray allData = new JSONArray();
+        int pageNumber = 1;
+        int pageSize = 50;
+        boolean hasMore = true;
+
+        while (hasMore) {
+            JSONObject searchParam = new JSONObject();
+            searchParam.put("appType", aliDingConfig.getAppType());
+            searchParam.put("systemToken", aliDingConfig.getSystemToken());
+            searchParam.put("userId", aliDingConfig.getUserId());
+            searchParam.put("formUuid", formUuid);
+            searchParam.put("currentPage", pageNumber);
+            searchParam.put("pageSize", pageSize);
+
+            if (StringUtils.isNotEmpty(searchFieldJson)) {
+                searchParam.put("searchFieldJson", searchFieldJson);
+            }
+
+            searchParam.put("orderConfigJson", "{\"gmt_modified\":\"+\"}");
+
+            if (lastSyncTime != null) {
+                String startTime = lastSyncTime.plusSeconds(1)
+                        .atZone(ZoneId.systemDefault())
+                        .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+                searchParam.put("modifiedFromTimeGMT", startTime);
+            }
+
+            String endTime = LocalDateTime.now()
+                    .atZone(ZoneId.systemDefault())
+                    .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+            searchParam.put("modifiedToTimeGMT", endTime);
+
+            String dataRes = HttpUtils.sendPostJson(
+                    aliDingConfig.getSearchFormDataUrl(),
+                    searchParam.toJSONString(),
+                    StandardCharsets.UTF_8.name(),
+                    null,
+                    accessToken
+            );
+
+            if (StringUtils.isEmpty(dataRes)) {
+                log.warn("绗� {} 椤垫媺鍙栨暟鎹负绌�", pageNumber);
+                break;
+            }
+
+            JSONObject resultObj = JSON.parseObject(dataRes);
+            JSONArray dataArr = resultObj.getJSONArray("data");
+            Integer totalCount = resultObj.getInteger("totalCount");
+
+            if (dataArr == null || dataArr.isEmpty()) {
+                log.info("娌℃湁鏇村鏂版暟鎹渶瑕佸悓姝�");
+                break;
+            }
+            allData.addAll(dataArr);
+            hasMore = (pageNumber * pageSize) < totalCount;
+            pageNumber++;
+
+            log.info("姝e湪鎻愬彇瀹滄惌鍒嗛〉鏁版嵁锛岀 {} 椤靛凡澶勭悊锛屽綋鍓嶆彁鍙栨暟: {}/{}", pageNumber - 1, allData.size(), totalCount);
+        }
+
+        return allData;
+    }
+
+    /**
+     * 鑾峰彇閽夐拤 AccessToken
+     */
+    private static String getAccessToken(AliDingConfig aliDingConfig) {
+        String params = "appkey=" + aliDingConfig.getAppKey() + "&appsecret=" + aliDingConfig.getAppSecret();
+        String tokenRes = HttpUtils.sendGet(aliDingConfig.getAccessTokenUrl(), params);
+        JSONObject tokenObj = JSON.parseObject(tokenRes);
+        String accessToken = tokenObj.getString("access_token");
+        if (StringUtils.isEmpty(accessToken)) {
+            log.error("鑾峰彇閽夐拤AccessToken澶辫触: {}", tokenRes);
+        }
+        return accessToken;
+    }
+
+    /**
+     * 鏃ユ湡鏍煎紡鍖�
+     *
+     * @param utcString 鏃ユ湡
+     * @return LocalDateTime
+     */
+    public static LocalDateTime parseUtcTime(String utcString) {
+        if (StringUtils.isEmpty(utcString)) {
+            return null;
+        }
+        try {
+            OffsetDateTime odt = OffsetDateTime.parse(utcString);
+            return odt.toLocalDateTime();
+        } catch (DateTimeParseException ex) {
+            log.warn("瑙f瀽鏃堕棿 {} 澶辫触: {}", utcString, ex.getMessage());
+            return null;
+        }
+    }
+
+    private static <T> LocalDateTime getLastSyncTime(IService<T> service, SFunction<T, ?> timeField) {
+        LambdaQueryWrapper<T> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.orderByDesc(timeField).last("LIMIT 1");
+        T lastRecord = service.getOne(queryWrapper);
+        if (lastRecord == null) {
+            return null;
+        }
+        try {
+            Method writeReplace = timeField.getClass().getDeclaredMethod("writeReplace");
+            writeReplace.setAccessible(true);
+            SerializedLambda lambda = (SerializedLambda) writeReplace.invoke(timeField);
+            // 鑾峰彇鏂规硶鍚�
+            String methodName = lambda.getImplMethodName();
+            // 杞瓧娈靛悕
+            String fieldName = methodName.substring(3, 4).toLowerCase() + methodName.substring(4);
+            Field field = lastRecord.getClass().getDeclaredField(fieldName);
+            field.setAccessible(true);
+            return (LocalDateTime) field.get(lastRecord);
+        } catch (Exception e) {
+            throw new RuntimeException("鑾峰彇鏈�鍚庡悓姝ユ椂闂村け璐�", e);
+        }
+    }
+}

--
Gitblit v1.9.3