Parcourir la source

日志系统以及异步。

skyfffire il y a 1 mois
Parent
commit
449720fad3

+ 3 - 0
.gitignore

@@ -8,6 +8,9 @@ target/
 ### Maven ###
 .mvn
 
+### Logs ###
+logs
+
 ### Eclipse ###
 .apt_generated
 .classpath

+ 15 - 0
pom.xml

@@ -65,6 +65,21 @@
             <artifactId>sms</artifactId>
             <version>1.2.0</version>
         </dependency>
+
+        <!-- SLF4J API -->
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.7.36</version> <!-- 推荐使用 SLF4J 1.7.x 系列,兼容性更广 -->
+            <!-- 如果你的 Java 版本>=1.8,也可以考虑 SLF4J 2.x,但需要注意用法更新 -->
+        </dependency>
+
+        <!-- Logback Classic (SLF4J 的实现) -->
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <version>1.2.11</version> <!-- 匹配 SLF4J 1.7.x 的最新版本 -->
+        </dependency>
     </dependencies>
 
     <build>

BIN
src/doc/技术实现奖励制度.docx


+ 59 - 0
src/main/java/common/jfinal/AppConfig.java

@@ -15,8 +15,16 @@ import modules.nftt.NfttController;
 import modules.order.OrderController;
 import modules.upload.UploadController;
 import modules.user.UserController;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory; // 导入这两个类
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 
 public class AppConfig extends JFinalConfig {
+    public static final Logger LOGGER = LoggerFactory.getLogger(AppConfig.class);
+
     static String DB_URL = System.getenv("DB_URL");
     static String DB_USER = System.getenv("DB_USER");
     static String DB_PASSWORD = System.getenv("DB_PASSWORD");
@@ -67,6 +75,30 @@ public class AppConfig extends JFinalConfig {
         // 映射实体
         _MappingKit.mapping(arp);
         plugins.add(arp);
+
+        // 初始化异步任务线程池
+        // 核心线程数:根据CPU核数和任务类型调整
+        // 最大线程数:通常是核心线程数的2倍,防止任务堆积
+        // 队列容量:根据任务队列积压情况调整
+        int corePoolSize = Runtime.getRuntime().availableProcessors();
+        int maxPoolSize = corePoolSize * 2;
+        int queueCapacity = 1000; // 适当大的队列,防止任务丢失
+
+        // 或 AbortPolicy, DiscardPolicy
+        // 全局线程池
+        ExecutorService asyncTaskExecutor = new ThreadPoolExecutor(
+                corePoolSize,
+                maxPoolSize,
+                60L,
+                TimeUnit.SECONDS,
+                new LinkedBlockingQueue<>(queueCapacity),
+                new ThreadPoolExecutor.CallerRunsPolicy() // 或 AbortPolicy, DiscardPolicy
+        );
+        LOGGER.info("异步任务线程池初始化成功,核心线程数: {}, 最大线程数: {}, 队列容量: {}", corePoolSize, maxPoolSize, queueCapacity);
+        // 可以将 ExecutorService 实例保存到某个单例类或 JFinal 的共享属性中,方便在其他地方访问
+        // me.set("asyncTaskExecutor", asyncTaskExecutor); // 不推荐直接用put,使用自己的全局Manager
+        // 更好的方式是创建一个单例的 TaskScheduler
+        TaskScheduler.init(asyncTaskExecutor);
     }
 
     @Override
@@ -83,4 +115,31 @@ public class AppConfig extends JFinalConfig {
     public void configHandler(Handlers handlers) {
         handlers.add(new AllCorsHandler());
     }
+
+    // TaskScheduler.java (建议创建的全局单例类,用于管理线程池)
+    public static class TaskScheduler {
+        private static ExecutorService executor;
+
+        // 私有构造器防止外部实例化
+        private TaskScheduler() {}
+
+        public static void init(ExecutorService executorService) {
+            if (executor != null) {
+                LOGGER.warn("TaskScheduler 已经初始化过,请勿重复初始化。");
+                return;
+            }
+            executor = executorService;
+        }
+
+        public static void submit(Runnable task) {
+            if (executor == null || executor.isShutdown()) {
+                LOGGER.error("TaskScheduler 未初始化或已关闭,无法提交任务!");
+                return;
+            }
+            executor.submit(task);
+        }
+
+        // 如果需要返回结果,使用 Callable
+        // public static <T> Future<T> submit(Callable<T> task) { ... }
+    }
 }

+ 7 - 6
src/main/java/common/utils/bsn/BsnSDK.java

@@ -3,6 +3,7 @@ package common.utils.bsn;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.jfinal.kit.HttpKit;
+import common.jfinal.AppConfig;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -93,21 +94,21 @@ public class BsnSDK {
     
     public static void main(String[] args) {
         try {
-            // System.out.println(accountInfo());
+            // AppConfig.LOGGER.info(accountInfo());
             // {"code":-1,"errorLogCode":"ERR:SL-ST_OAI1b264496b3b6477c99e3dc083b02f5bd52_1758076191510_ED","message":"MSG_10051035"}
             // {"code":0,"data":{"privateKey":"xxx","opbChainClientAddress":"0xcf6203a04a418d765141d285a9956c8046f1a343","publicKey":"xxx","opbChainClientName":"DLTBH_10002"},"errorLogMessage":"","message":"MSG_00000"}
-            // System.out.println(createChainAccount("DLTBH_10002"));
+            // AppConfig.LOGGER.info(createChainAccount("DLTBH_10002"));
             
-            // System.out.println(createNft("nft", "http://117.72.208.239/uploads/20250910/2e9f839835224bb68726743caaa1a6b2.png", 100, "DLTBH_NFT_1"));
+            // AppConfig.LOGGER.info(createNft("nft", "http://117.72.208.239/uploads/20250910/2e9f839835224bb68726743caaa1a6b2.png", 100, "DLTBH_NFT_1"));
             // {"code":0,"data":{"txHash":"79444b6937494ed1c5fa605fc439653dfff8074696a84c70cbaf6127a3cbcb2a","status":0},"errorLogMessage":"","message":"MSG_00000"}
             // {"code":0,"data":{"txStatus":0,"tokenId":"144498","txHash":"0x79444b6937494ed1c5fa605fc439653dfff8074696a84c70cbaf6127a3cbcb2a","status":1},"errorLogMessage":"","message":"MSG_00000"}
-            // System.out.println(search("DLTBH_NFT_1"));
+            // AppConfig.LOGGER.info(search("DLTBH_NFT_1"));
 
             // {"code":0,"errorLogMessage":"","message":"MSG_00000"}
-            // System.out.println(sendNft("0xe84cc57ea90db89e3a65bc704ce57198cc32daa0", 1000, "144498", "DLTBH_ORDER_101"));
+            // AppConfig.LOGGER.info(sendNft("0xe84cc57ea90db89e3a65bc704ce57198cc32daa0", 1000, "144498", "DLTBH_ORDER_101"));
             // {"code":0,"data":{"txStatus":0,"tokenId":"144498","txHash":"0x45a75d406dadad4b14d1aa148f87d34788db7ac5721cd653344d81da7395f7d4","status":1},"errorLogMessage":"","message":"MSG_00000"}
             // {"code":0,"data":{"txStatus":1,"txStatusMsg":"DDC1155:insufficient balance","tokenId":"144498","txHash":"0xc997b7c6790fbc7ea8d9b0753da25f215c781303dc7d9172e79cb89f48568eed","failMessage":"0x16:null","status":2},"errorLogMessage":"","message":"MSG_00000"}
-            System.out.println(search("DLTBH_ORDER_101"));
+            AppConfig.LOGGER.info(search("DLTBH_ORDER_101").toJSONString());
         } catch (Exception e) {
             e.printStackTrace();
         }

+ 17 - 15
src/main/java/common/utils/hyg/AESUtils.java

@@ -1,5 +1,7 @@
 package common.utils.hyg;
 
+import common.jfinal.AppConfig;
+
 import javax.crypto.Cipher;
 import javax.crypto.KeyGenerator;
 import javax.crypto.SecretKey;
@@ -188,53 +190,53 @@ public class AESUtils {
         try {
             // 1. 自动生成AES密钥
             String aesKey = getAutoCreateAESKey();
-            System.out.println("生成的AES密钥 (Base64编码): " + aesKey);
+            AppConfig.LOGGER.info("生成的AES密钥 (Base64编码): " + aesKey);
 
             String originalContent = "这是一段需要加密的中文文本!Hello World! 12345.";
-            System.out.println("原始内容: " + originalContent);
+            AppConfig.LOGGER.info("原始内容: " + originalContent);
 
             // 2. 使用生成的密钥进行加密
             String encryptedHex = encrypt2Hex(originalContent, aesKey);
-            System.out.println("加密后的内容 (Hex): " + encryptedHex);
+            AppConfig.LOGGER.info("加密后的内容 (Hex): " + encryptedHex);
 
             // 3. 使用相同的密钥进行解密
             String decryptedContent = decryptByHex(encryptedHex, aesKey);
-            System.out.println("解密后的内容: " + decryptedContent);
+            AppConfig.LOGGER.info("解密后的内容: " + decryptedContent);
 
             // 4. 验证加密解密是否一致
             if (originalContent.equals(decryptedContent)) {
-                System.out.println("加密解密验证成功!");
+                AppConfig.LOGGER.info("加密解密验证成功!");
             } else {
-                System.out.println("加密解密验证失败!");
+                AppConfig.LOGGER.info("加密解密验证失败!");
             }
 
             // --- 尝试使用固定的短密钥 (不推荐用于生产环境,仅为测试演示) ---
-            System.out.println("\n--- 使用固定密钥演示 ---");
+            AppConfig.LOGGER.info("\n--- 使用固定密钥演示 ---");
             // 注意: 固定密钥的Base64解码后长度必须是16, 24, 32字节 (对应128, 192, 256位)
             // 这是一个随机生成的16字节密钥的Base64编码,直接硬编码,实际应用中应避免
             String fixedKeyBase64 = "yL4k/J11mR82tH+a+3M69g=="; // 这是一个随机生成的16字节密钥的Base64编码
 
-            System.out.println("固定密钥 (Base64编码): " + fixedKeyBase64);
+            AppConfig.LOGGER.info("固定密钥 (Base64编码): " + fixedKeyBase64);
             String fixedContent = "测试固定密钥加密解密。";
-            System.out.println("原始固定内容: " + fixedContent);
+            AppConfig.LOGGER.info("原始固定内容: " + fixedContent);
 
             String fixedEncryptedHex = encrypt2Hex(fixedContent, fixedKeyBase64);
-            System.out.println("固定密钥加密后的内容 (Hex): " + fixedEncryptedHex);
+            AppConfig.LOGGER.info("固定密钥加密后的内容 (Hex): " + fixedEncryptedHex);
 
             String fixedDecryptedContent = decryptByHex(fixedEncryptedHex, fixedKeyBase64);
-            System.out.println("固定密钥解密后的内容: " + fixedDecryptedContent);
+            AppConfig.LOGGER.info("固定密钥解密后的内容: " + fixedDecryptedContent);
 
             if (fixedContent.equals(fixedDecryptedContent)) {
-                System.out.println("固定密钥加密解密验证成功!");
+                AppConfig.LOGGER.info("固定密钥加密解密验证成功!");
             } else {
-                System.out.println("固定密钥加密解密验证失败!");
+                AppConfig.LOGGER.info("固定密钥加密解密验证失败!");
             }
 
         } catch (NoSuchAlgorithmException e) {
-            System.err.println("错误:不支持的加密算法。" + e.getMessage());
+            AppConfig.LOGGER.error("错误:不支持的加密算法。" + e.getMessage());
             e.printStackTrace();
         } catch (Exception e) {
-            System.err.println("加密解密过程中发生错误:" + e.getMessage());
+            AppConfig.LOGGER.error("加密解密过程中发生错误:" + e.getMessage());
             e.printStackTrace();
         }
     }

+ 3 - 2
src/main/java/common/utils/hyg/HygSDK.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.jfinal.kit.HttpKit;
 import com.jfinal.kit.StrKit;
+import common.jfinal.AppConfig;
 
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
@@ -100,8 +101,8 @@ public class HygSDK {
         try {
             // {"data":{"workerId":"W141720xxxx8","identNo":"51xxxx1xxxxx9012","signTime":"2025-09-15 17:36:50","bankCardNo":"6217003xxxxx1392931","workerCfcaSignFlag":true,"signDesc":"签约成功","remark":"","updateTime":"2025-09-16 03:15:00","signState":2,"receiptChannel":10,"createTime":"2025-09-15 17:36:50","workerMobile":"17781855864","verifiedStatus":2,"verifiedDesc":"认证成功","workerName":"龚成明","verifiedTime":"2025-09-15 17:36:17","certificateType":1},"statusText":"success","statusCode":"000000"}
             // {"statusText":"用户记录不存在","statusCode":"200406"}
-            System.out.println(HygSDK.findWorkerDetails(""));
-            // System.out.println(HygSDK.findDepositAccount());
+            AppConfig.LOGGER.info(HygSDK.findWorkerDetails("").toString());
+            // AppConfig.LOGGER.info(HygSDK.findDepositAccount());
         } catch (Exception e) {
             e.printStackTrace();
         }

+ 28 - 27
src/main/java/common/utils/hyg/RSAUtils.java

@@ -1,6 +1,7 @@
 package common.utils.hyg;
 
 import com.jfinal.kit.StrKit;
+import common.jfinal.AppConfig;
 
 import javax.crypto.Cipher;
 import java.io.ByteArrayOutputStream;
@@ -286,64 +287,64 @@ public class RSAUtils {
             String publicKey = getPublicKey(keyMap);
             String privateKey = getPrivateKey(keyMap);
 
-            System.out.println("--- RSA 密钥对生成 ---");
-            System.out.println("公钥 (Base64编码):\n" + publicKey);
-            System.out.println("私钥 (Base64编码):\n" + privateKey);
-            System.out.println("----------------------\n");
+            AppConfig.LOGGER.info("--- RSA 密钥对生成 ---");
+            AppConfig.LOGGER.info("公钥 (Base64编码):\n" + publicKey);
+            AppConfig.LOGGER.info("私钥 (Base64编码):\n" + privateKey);
+            AppConfig.LOGGER.info("----------------------\n");
 
             String originalContent = "这是一段需要使用RSA加密和签名的中文文本,包含较长的内容,以测试分段处理。Hello World! 1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
-            System.out.println("原始数据: " + originalContent);
+            AppConfig.LOGGER.info("原始数据: " + originalContent);
             byte[] dataBytes = originalContent.getBytes(StandardCharsets.UTF_8);
 
             // 2. 公钥加密,私钥解密 (实现数据机密性)
-            System.out.println("--- 公钥加密,私钥解密 ---");
+            AppConfig.LOGGER.info("--- 公钥加密,私钥解密 ---");
             byte[] encryptedByPublicKey = encryptByPublicKey(dataBytes, publicKey);
-            System.out.println("公钥加密后的数据 (Base64编码): " + Base64.getEncoder().encodeToString(encryptedByPublicKey));
+            AppConfig.LOGGER.info("公钥加密后的数据 (Base64编码): " + Base64.getEncoder().encodeToString(encryptedByPublicKey));
 
             byte[] decryptedByPrivateKey = decryptByPrivateKey(encryptedByPublicKey, privateKey);
             String decryptedString = new String(decryptedByPrivateKey, StandardCharsets.UTF_8);
-            System.out.println("私钥解密后的数据: " + decryptedString);
-            System.out.println("验证一致性: " + originalContent.equals(decryptedString));
-            System.out.println("----------------------\n");
+            AppConfig.LOGGER.info("私钥解密后的数据: " + decryptedString);
+            AppConfig.LOGGER.info("验证一致性: " + originalContent.equals(decryptedString));
+            AppConfig.LOGGER.info("----------------------\n");
 
             // 3. 私钥加密,公钥解密 (实现数字签名,通常不用于传输数据)
-            System.out.println("--- 私钥加密,公钥解密 (常用于签名验证) ---");
+            AppConfig.LOGGER.info("--- 私钥加密,公钥解密 (常用于签名验证) ---");
             byte[] encryptedByPrivateKey = encryptByPrivateKey(dataBytes, privateKey);
-            System.out.println("私钥加密后的数据 (Base64编码): " + Base64.getEncoder().encodeToString(encryptedByPrivateKey));
+            AppConfig.LOGGER.info("私钥加密后的数据 (Base64编码): " + Base64.getEncoder().encodeToString(encryptedByPrivateKey));
 
             byte[] decryptedByPublicKey = decryptByPublicKey(encryptedByPrivateKey, publicKey);
             String decryptedString2 = new String(decryptedByPublicKey, StandardCharsets.UTF_8);
-            System.out.println("公钥解密后的数据: " + decryptedString2);
-            System.out.println("验证一致性: " + originalContent.equals(decryptedString2));
-            System.out.println("----------------------\n");
+            AppConfig.LOGGER.info("公钥解密后的数据: " + decryptedString2);
+            AppConfig.LOGGER.info("验证一致性: " + originalContent.equals(decryptedString2));
+            AppConfig.LOGGER.info("----------------------\n");
 
             // 4. 数字签名与验证 (主流用法)
-            System.out.println("--- 数字签名与验证 ---");
+            AppConfig.LOGGER.info("--- 数字签名与验证 ---");
             String sign = sign(dataBytes, privateKey);
-            System.out.println("生成的签名 (Base64编码): " + sign);
+            AppConfig.LOGGER.info("生成的签名 (Base64编码): " + sign);
 
             // 验证正确的签名
             boolean verified = verify(dataBytes, publicKey, sign);
-            System.out.println("验证签名结果 (正确数据与签名): " + verified);
+            AppConfig.LOGGER.info("验证签名结果 (正确数据与签名): " + verified);
 
             // 验证篡改后的数据
             byte[] tamperedData = "这是被篡改的数据".getBytes(StandardCharsets.UTF_8);
             boolean tamperedVerified = verify(tamperedData, publicKey, sign);
-            System.out.println("验证签名结果 (篡改数据与原签名): " + tamperedVerified);
+            AppConfig.LOGGER.info("验证签名结果 (篡改数据与原签名): " + tamperedVerified);
 
             // 验证错误的签名
             String wrongSign = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
             try {
                 boolean wrongSignVerified = verify(dataBytes, publicKey, wrongSign);
-                System.out.println("验证签名结果 (正确数据与错误签名): " + wrongSignVerified);
+                AppConfig.LOGGER.info("验证签名结果 (正确数据与错误签名): " + wrongSignVerified);
             } catch (IllegalArgumentException e) {
-                System.out.println("验证签名结果 (正确数据与错误签名): Base64解码错误,签名非法。");
+                AppConfig.LOGGER.info("验证签名结果 (正确数据与错误签名): Base64解码错误,签名非法。");
             }
 
-            System.out.println("----------------------\n");
+            AppConfig.LOGGER.info("----------------------\n");
 
             // 5. sortParam 方法测试
-            System.out.println("--- sortParam 方法测试 ---");
+            AppConfig.LOGGER.info("--- sortParam 方法测试 ---");
             Map<String, Object> params = new TreeMap<>();
             params.put("appKey", "123");
             params.put("timestamp", System.currentTimeMillis());
@@ -353,13 +354,13 @@ public class RSAUtils {
             params.put("paramD", ""); // 测试空字符串
 
             String sortedAndConcatenated = sortParam(params);
-            System.out.println("原始参数Map: " + params);
-            System.out.println("排序拼接结果: " + sortedAndConcatenated);
+            AppConfig.LOGGER.info("原始参数Map: " + params);
+            AppConfig.LOGGER.info("排序拼接结果: " + sortedAndConcatenated);
 
-            System.out.println("----------------------\n");
+            AppConfig.LOGGER.info("----------------------\n");
 
         } catch (Exception e) {
-            System.err.println("发生了一个错误: " + e.getMessage());
+            AppConfig.LOGGER.error("发生了一个错误: " + e.getMessage());
             e.printStackTrace();
         }
     }

+ 4 - 3
src/main/java/common/utils/jdcloud/SMS.java

@@ -7,6 +7,7 @@ import com.jdcloud.sdk.http.HttpRequestConfig;
 import com.jdcloud.sdk.http.Protocol;
 import com.jdcloud.sdk.service.sms.client.SmsClient;
 import com.jdcloud.sdk.service.sms.model.*;
+import common.jfinal.AppConfig;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -71,7 +72,7 @@ public class SMS {
 //        phoneList.add("");
 //        statusReportRequest.setPhoneList(phoneList);
 //        StatusReportResponse response = smsClient.statusReport(statusReportRequest);
-//        System.out.println(new Gson().toJson(response));
+//        AppConfig.LOGGER.info(new Gson().toJson(response));
 //    }
 //
 //    /**
@@ -89,14 +90,14 @@ public class SMS {
 //        phoneList.add("");
 //        replyRequest.setPhoneList(phoneList);
 //        ReplyResponse response = smsClient.reply(replyRequest);
-//        System.out.println(new Gson().toJson(response));
+//        AppConfig.LOGGER.info(new Gson().toJson(response));
 //    }
 
     public static void main(String[ ] args) {
         // 初始化client
         init();
         BatchSendResponse response = sendVerifyCodeByMobileNumber("177****####", "3213");
-        System.out.println(JSONObject.toJSONString(response));
+        AppConfig.LOGGER.info(JSONObject.toJSONString(response));
         /*
         // testStatusReport();
         // testReply();

+ 5 - 4
src/main/java/common/utils/model/MyGenerator.java

@@ -1,6 +1,7 @@
 package common.utils.model;
 
 import com.jfinal.plugin.activerecord.generator.Generator;
+import common.jfinal.AppConfig;
 
 import javax.sql.DataSource;
 
@@ -25,28 +26,28 @@ public class MyGenerator {
     
     public MyGenerator setBaseModelPackageName(String baseModelPackageName) {
         this.baseModelPackageName = baseModelPackageName;
-        System.out.println("BaseModelPackageName: " + baseModelPackageName);
+        AppConfig.LOGGER.info("BaseModelPackageName: " + baseModelPackageName);
         
         return this;
     }
 
     public MyGenerator setBaseModelOutputDir(String baseModelOutputDir) {
         this.baseModelOutputDir = baseModelOutputDir;
-        System.out.println("BaseModelOutputDir: " + baseModelOutputDir);
+        AppConfig.LOGGER.info("BaseModelOutputDir: " + baseModelOutputDir);
 
         return this;
     }
 
     public MyGenerator setModelPackageName(String modelPackageName) {
         this.modelPackageName = modelPackageName;
-        System.out.println("ModelPackageName: " + modelPackageName);
+        AppConfig.LOGGER.info("ModelPackageName: " + modelPackageName);
 
         return this;
     }
 
     public MyGenerator setModelOutputDir(String modelOutputDir) {
         this.modelOutputDir = modelOutputDir;
-        System.out.println("ModelOutputDir: " + modelOutputDir);
+        AppConfig.LOGGER.info("ModelOutputDir: " + modelOutputDir);
 
         return this;
     }

+ 2 - 1
src/main/java/modules/nftt/NfttController.java

@@ -8,6 +8,7 @@ import com.jfinal.kit.StrKit;
 import common.interceptor.LoginInterceptor;
 import common.interceptor.empty.EmptyInterface;
 import common.interceptor.role.RequiredRoleInterface;
+import common.jfinal.AppConfig;
 import common.model.Nftt;
 import common.utils.bsn.BsnSDK;
 import common.utils.http.MyController;
@@ -153,7 +154,7 @@ public class NfttController extends MyController {
             nftt.set("is_deleted", 0); // 0表示未删除
 
             // 打印 Nftt 对象内部实际存储的属性,进行调试验证
-            System.out.println("Nftt Model 的内部数据 (for debug): " + nftt);
+            AppConfig.LOGGER.info("Nftt Model 的内部数据 (for debug): " + nftt);
 
             if (service.save(nftt)) {
                 // 在链上创建NFT

+ 2 - 1
src/main/java/modules/nftt/NfttService.java

@@ -3,6 +3,7 @@ package modules.nftt;
 import com.alibaba.fastjson.JSONObject;
 import com.jfinal.kit.StrKit;
 import com.jfinal.plugin.activerecord.Db;
+import common.jfinal.AppConfig;
 import common.model.Nftt;
 import common.utils.bsn.BsnSDK;
 
@@ -67,7 +68,7 @@ public class NfttService {
                     nftt.update();
                 }
             } catch (Exception e) {
-                System.err.println("search NFTT时出现问题:" + e.getMessage());
+                AppConfig.LOGGER.error("search NFTT时出现问题:" + e.getMessage());
             }
         }
         

+ 7 - 4
src/main/java/modules/order/OrderService.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.jfinal.kit.StrKit;
 import com.jfinal.plugin.activerecord.Db;
 import com.jfinal.plugin.activerecord.Record;
+import common.jfinal.AppConfig;
 import common.model.Nftt;
 import common.model.Order;
 import common.model.OrderLog;
@@ -207,7 +208,9 @@ public class OrderService {
                             order.setUpdateTime(System.currentTimeMillis());
                             
                             order.update();
-                            System.out.println("该订单已确权:" + order);
+                            AppConfig.LOGGER.info("该订单已确权:" + order);
+                            
+                            // TODO 交付成功之后触发分润逻辑,异步触发
                         }
                         
                         // status为2时是交付失败,自动执行退款
@@ -237,13 +240,13 @@ public class OrderService {
                             order.setUpdateTime(System.currentTimeMillis());
                             order.update();
                             
-                            System.err.println("该订单确权失败:" + order);
+                            AppConfig.LOGGER.error("该订单确权失败:" + order);
                         }
                     } else {
                         throw new RuntimeException(searchResponse.toJSONString());
                     }
                 } catch (Exception e) {
-                    System.err.println("查询转账信息执行失败:" + e.getMessage());
+                    AppConfig.LOGGER.error("查询转账信息执行失败:" + e.getMessage());
                 }
             } 
             // 未转账的先进行转账
@@ -271,7 +274,7 @@ public class OrderService {
                         throw new RuntimeException(transferResponse.toJSONString());
                     }
                 } catch (Exception e) {
-                    System.err.println("转账执行失败:" + e.getMessage());
+                    AppConfig.LOGGER.error("转账执行失败:" + e.getMessage());
                 }
             }
         }

+ 5 - 5
src/main/java/modules/user/UserController.java

@@ -9,13 +9,13 @@ import com.jfinal.kit.StrKit;
 import common.interceptor.LoginInterceptor;
 import common.interceptor.empty.EmptyInterface;
 import common.interceptor.role.RequiredRoleInterface;
+import common.jfinal.AppConfig;
 import common.model.DepositLog;
 import common.model.User;
 import common.utils.http.MyController;
 import common.utils.http.MyRet;
 import common.utils.http.VerifyCode;
 import common.utils.hyg.AESUtils;
-import common.utils.hyg.HygSDK;
 import common.utils.jdcloud.SMS;
 import modules.deposit.DepositLogService;
 
@@ -255,7 +255,7 @@ public class UserController extends MyController {
             // 对user进行升级
             user.update();
 
-            System.out.println(businessBody.toJSONString());
+            AppConfig.LOGGER.info(businessBody.toJSONString());
 
             Map<String, Object> responseJson = new HashMap<>();
             responseJson.put("statusCode", "000000");
@@ -267,7 +267,7 @@ public class UserController extends MyController {
             responseJson.put("statusCode", "100000");
             responseJson.put("statusText", "回调失败 " + e.getMessage());
 
-            System.out.println("回调失败 " + e.getMessage());
+            AppConfig.LOGGER.info("回调失败 " + e.getMessage());
 
             renderJson(responseJson);
         }
@@ -277,7 +277,7 @@ public class UserController extends MyController {
     public void hygDeposited() {
         JSONObject requestBodyJson = MyController.getJsonModelByRequestAndType(getRequest(), JSONObject.class);
 
-        System.out.println("hygDeposited " + requestBodyJson);
+        AppConfig.LOGGER.info("hygDeposited " + requestBodyJson);
 
         // 每条回调都保存到数据库
         DepositLog log = new DepositLog();
@@ -327,7 +327,7 @@ public class UserController extends MyController {
             responseJson.put("statusCode", "100000");
             responseJson.put("statusText", "回调失败 " + e.getMessage());
 
-            System.out.println("回调失败 " + e.getMessage());
+            AppConfig.LOGGER.info("回调失败 " + e.getMessage());
 
             renderJson(responseJson);
 

+ 2 - 1
src/main/java/modules/user/UserService.java

@@ -3,6 +3,7 @@ package modules.user;
 import com.alibaba.fastjson.JSONObject;
 import com.jfinal.kit.StrKit;
 import com.jfinal.plugin.activerecord.Db;
+import common.jfinal.AppConfig;
 import common.model.User;
 import common.utils.bsn.BsnSDK;
 import common.utils.http.MyRet;
@@ -141,7 +142,7 @@ public class UserService {
                     user.update();
                 }
             } catch (Exception e) {
-                System.err.println("慧用工接口调取错误:" + e.getMessage());
+                AppConfig.LOGGER.error("慧用工接口调取错误:" + e.getMessage());
             }
         }
     }

+ 55 - 0
src/main/resources/logback.xml

@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+
+    <!-- Console Appender -->
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <!-- Pattern of output message: timestamp threadLevel loggerName - message_content line_separator -->
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <!-- File Appender -->
+    <!-- Log到文件,支持按日期和文件大小自动归档 -->
+    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 文件名模板 -->
+        <file>logs/application.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- daily rollover -->
+            <fileNamePattern>logs/application.%d{yyyy-MM-dd}.log</fileNamePattern>
+            <!-- keep 30 days' worth of history -->
+            <maxHistory>30</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <!-- Root Logger (默认Logger) -->
+    <!-- level: 指定默认日志级别:TRACE, DEBUG, INFO, WARN, ERROR。 -->
+    <!-- additivity: 是否向上级Logger传递日志事件,通常保持true -->
+    <root level="INFO">
+        <appender-ref ref="STDOUT" />
+        <appender-ref ref="FILE" />
+    </root>
+
+    <!-- 特定Logger的配置 -->
+    <!-- 可以针对特定包或类设置日志级别 -->
+    <logger name="com.yourpackage" level="DEBUG" additivity="false">
+        <appender-ref ref="STDOUT" />
+        <appender-ref ref="FILE" />
+    </logger>
+
+    <!-- JFinal 相关的日志级别可以根据需要调整 -->
+    <logger name="com.jfinal" level="INFO" additivity="false">
+        <appender-ref ref="STDOUT" />
+        <appender-ref ref="FILE" />
+    </logger>
+
+    <!-- 数据库连接池 Druid 的日志,可以设置为 INFO 减少输出 -->
+    <logger name="com.alibaba.druid" level="INFO" additivity="false">
+        <appender-ref ref="STDOUT" />
+        <appender-ref ref="FILE" />
+    </logger>
+
+</configuration>