Răsfoiți Sursa

带搜索分页的NFT搜索

skyfffire 1 lună în urmă
părinte
comite
65985bfd69

+ 13 - 10
src/main/java/modules/nftt/NfttController.java

@@ -154,7 +154,7 @@ public class NfttController extends MyController {
             nftt.set("is_deleted", 0); // 0表示未删除
 
             // 打印 Nftt 对象内部实际存储的属性,进行调试验证
-            AppConfig.LOGGER.info("Nftt Model 的内部数据 (for debug): " + nftt);
+            AppConfig.LOGGER.info("Nftt Model 的内部数据 (for debug): {}", nftt);
 
             if (service.save(nftt)) {
                 // 在链上创建NFT
@@ -327,9 +327,10 @@ public class NfttController extends MyController {
             renderJson(MyRet.fail("更新失败,请将此日志复制给开发者" + nftt).setData(nftt));
         }
     }
-    
-    @Before(LoginInterceptor.class)
-    @RequiredRoleInterface({UserController.ROLE_CHECK_ADMIN, UserController.ROLE_SUPER_ADMIN})
+
+    /**
+     * nftt查询
+     */
     @EmptyInterface({"page_size", "page_number"})
     public void nftts() {
         JSONObject requestBodyJson = MyController.getJsonModelByRequestAndType(getRequest(), JSONObject.class);
@@ -363,18 +364,20 @@ public class NfttController extends MyController {
             renderJson(MyRet.fail("页码(page_number)格式不正确: " + e.getMessage()));
             return;
         }
+        
+        String keywords = requestBodyJson.getString("keywords");
 
         // 最终结果封装
-        List<Nftt> nftts = service.nfttList(pageNumberInt, pageSizeInt);
-        Integer totalNftts = service.count();
+        List<Nftt> nfttList = service.nfttList(pageNumberInt, pageSizeInt, keywords);
+        long nfttCount = service.count(keywords);
 
         Map<String, Object> response = new HashMap<>();
-        response.put("list", nftts);
-        response.put("total_row", nftts.toArray().length);
-        response.put("total_page", 1 + (nftts.toArray().length / pageSizeInt));
+        response.put("list", nfttList);
+        response.put("total_row", nfttList.toArray().length);
+        response.put("total_page", 1 + (nfttList.toArray().length / pageSizeInt));
         response.put("page_size", pageSizeInt);
         response.put("page_number", pageNumberInt);
-        response.put("total_user_count", totalNftts);
+        response.put("total_user_count", nfttCount);
 
         renderJson(MyRet.ok("查询成功").setData(response));
     }

+ 96 - 24
src/main/java/modules/nftt/NfttService.java

@@ -7,6 +7,7 @@ import common.jfinal.AppConfig;
 import common.model.Nftt;
 import common.utils.bsn.BsnSDK;
 
+import java.util.ArrayList;
 import java.util.List;
 
 public class NfttService {
@@ -22,10 +23,27 @@ public class NfttService {
         return Nftt.dao.findById(id);
     }
 
-    public Integer count() {
-        String sql = "SELECT COUNT(1) FROM t_nftt";
+    /**
+     * 查询 NFTT 记录的总数量,支持按名称进行模糊搜索
+     * 如果 keywords 为 null 或空字符串,则返回所有记录的总数。
+     *
+     * @param keywords 可选参数,用于 name 字段的模糊匹配。
+     * @return 符合条件的 NFTT 记录总数
+     */
+    public long count(String keywords) { // 建议返回 long 类型,防止数量过大 Integer 溢出
+        StringBuilder sqlBuilder = new StringBuilder("SELECT COUNT(id) FROM t_nftt"); // 使用 COUNT(id) 更明确
 
-        return Db.queryInt(sql);
+        List<Object> params = new ArrayList<>(); // 用于存储 SQL 参数
+
+        // ✅ 添加关键词搜索逻辑
+        if (StrKit.notBlank(keywords)) {
+            sqlBuilder.append(" WHERE name LIKE ?"); // 添加 WHERE 子句
+            params.add("%" + keywords + "%");        // 添加模糊匹配参数
+        }
+
+        // 执行查询
+        // Db.queryLong() 返回 long 类型,更安全
+        return Db.queryLong(sqlBuilder.toString(), params.toArray());
     }
 
     public List<Nftt> homeList() {
@@ -35,40 +53,94 @@ public class NfttService {
         return Nftt.dao.find(baseSql);
     }
 
-    public List<Nftt> nfttList(int pageNumber, int pageSize) {
+    /**
+     * 分页查询 NFT 商品列表,并支持按名称模糊搜索
+     * 如果 NFT 未上链成功,会尝试查询其上链状态并更新
+     *
+     * @param pageNumber 页码
+     * @param pageSize 每页大小
+     * @param keywords   可选参数,用于 name 字段的模糊匹配。如果为 null 或空字符串则不进行过滤。
+     * @return 符合条件的 NFT 列表
+     */
+    public List<Nftt> nfttList(int pageNumber, int pageSize, String keywords) { // 增加 keywords 参数
         int offset = (pageNumber - 1) * pageSize;
-        
+
         String columns = "*";
-        String baseSql = "select " + columns + " from t_nftt order by buying_start_time desc limit ?, ?";
-        
-        List<Nftt> list = Nftt.dao.find(baseSql, offset, pageSize);
+        StringBuilder sqlBuilder = new StringBuilder("select ").append(columns).append(" from t_nftt");
+
+        List<Object> params = new ArrayList<>(); // 用于存储 SQL 参数
+
+        // ✅ 添加关键词搜索逻辑
+        if (StrKit.notBlank(keywords)) {
+            sqlBuilder.append(" where name like ?"); // 添加 WHERE 子句
+            params.add("%" + keywords + "%");        // 添加模糊匹配参数
+        }
+
+        sqlBuilder.append(" order by buying_start_time desc limit ?, ?"); // 添加排序和分页
+        params.add(offset);
+        params.add(pageSize);
 
+        // 执行查询
+        // Nftt.dao.find() 的参数:第一位是 SQL 字符串,后面是可变参数数组
+        // 这里需要将 List<Object> params 转换为 Object[]
+        List<Nftt> list = Nftt.dao.find(sqlBuilder.toString(), params.toArray());
+
+        // 遍历列表,处理 BSN 状态更新逻辑
+        // 这个逻辑会影响分页查询的性能,特别是当 BsnSDK.search 是耗时操作时
+        // 建议将其移到异步处理或专门的同步任务中
         for (Nftt nftt : list) {
-            if (StrKit.notBlank(nftt.getBsnTokenId())) {
+            // bsnTokenId 如果不为空,说明已经处理过上链结果,跳过
+            if (StrKit.notBlank(nftt.getStr("bsn_token_id"))) { // 假设字段名为 bsn_token_id
                 continue;
             }
 
             try {
-                JSONObject searchObject = BsnSDK.search("DLTBH_NFT_" + nftt.getId());
-                nftt.setBsnStatusJson(searchObject.toJSONString());
-                nftt.update();
-                
-                if (searchObject.getInteger("code") != 0) {
-                    throw new RuntimeException("查询失败,返回值与预期不符:" + searchObject.toJSONString());
+                // 调用 BSN SDK 查询上链状态
+                // 确保 BsnSDK.search 返回的是 JSONObject,且参数正确
+                JSONObject searchObject = BsnSDK.search("DLTBH_NFT_" + nftt.getLong("id")); // 假设 id 是 Long 类型
+
+                // 记录原始响应,便于调试
+                nftt.set("bsn_status_json", searchObject.toJSONString()); // 假设字段名为 bsn_status_json
+                // 不需要在这里立即 update(),可以在最后处理完所有状态后再批量更新,或在成功时更新
+                // nftt.update(); // 暂时移除,避免频繁更新
+
+                // 校验 BSN SDK 响应
+                if (searchObject.getInteger("code") == null || searchObject.getInteger("code") != 0) {
+                    throw new RuntimeException("BSN API查询失败,返回值与预期不符或code不为0:" + searchObject.toJSONString());
                 }
-                
+
                 JSONObject data = searchObject.getJSONObject("data");
-                if (data.getInteger("status") == 2) {
-                    nftt.setBsnTokenId("-1");
-                    throw new RuntimeException("上链失败,链上的错误:" + searchObject.toJSONString());
+                if (data == null) {
+                    throw new RuntimeException("BSN API响应数据为空:" + searchObject.toJSONString());
                 }
-                
-                if (data.getInteger("status") == 1) {
-                    nftt.setBsnTokenId(data.getString("tokenId"));
-                    nftt.update();
+
+                Integer status = data.getInteger("status");
+                if (status == null) {
+                    throw new RuntimeException("BSN API响应状态字段缺失:" + searchObject.toJSONString());
+                }
+
+                if (status == 2) { // 假设 status == 2 表示上链失败
+                    nftt.set("bsn_token_id", "-1"); // 标记上链失败
+                    nftt.set("bsn_status_json", searchObject.toJSONString()); // 更新失败状态信息
+                    nftt.update(); // 立即更新失败状态
+                    throw new RuntimeException("BSN 上链失败,链上的错误:" + searchObject.toJSONString());
+                }
+
+                if (status == 1) { // 假设 status == 1 表示上链成功且有 tokenId
+                    String tokenId = data.getString("tokenId");
+                    if (StrKit.isBlank(tokenId)) {
+                        throw new RuntimeException("BSN 上链成功但 tokenId 为空:" + searchObject.toJSONString());
+                    }
+                    nftt.set("bsn_token_id", tokenId);
+                    nftt.set("bsn_status_json", searchObject.toJSONString()); // 更新成功状态信息
+                    nftt.update(); // 立即更新成功状态
                 }
+                // 如果 status 是其他值,可能表示正在处理中,不更新 bsn_token_id
             } catch (Exception e) {
-                AppConfig.LOGGER.error("search NFTT时出现问题:" + e.getMessage());
+                // 记录错误日志,但通常不应该影响整个列表的返回
+                AppConfig.LOGGER.error("查询并更新NFT {} 的BSN状态时出现问题:{}", nftt.getLong("id"), e.getMessage(), e);
+                // 这里可以选择不throw,或者throw RuntimeException让上层捕获
+                // 如果是服务故障,可能需要全局捕获并告警
             }
         }
         

+ 18 - 17
src/test/rest/NfttControllerTest.http

@@ -15,6 +15,24 @@ POST {{ baseUrl }}/nftt/homeList
 Content-Type: application/json
 dl-token: {{dl_token_var}}
 
+### nftt搜索
+POST {{ baseUrl }}/nftt/nftts
+Content-Type: application/json
+dl-token: {{dl_token_var}}
+
+{
+  "page_number": 1,
+  "page_size": 100,
+  "keywords": ""
+}
+### 返回值解释
+### list 分页结果的实际列表数据 
+### page_number 当前页码
+### page_size 每页大小
+### total_page 总页数
+### total_row  当前分页的总数
+### total_nftt_count 符合条件的总记录数
+
 ### 【审核管理员、超级管理员】NFT模板创建接口
 POST {{ baseUrl }}/nftt/create
 Content-Type: application/json
@@ -56,20 +74,3 @@ dl-token: {{dl_token_var}}
     "https://jfinal.com/upload/img/share/0/61566_20201109163400.jpg"
   ]
 }
-
-### 【审核管理员、超级管理员】获取nftts列表,当前版本没有搜索条件
-POST {{ baseUrl }}/nftt/nftts
-Content-Type: application/json
-dl-token: {{dl_token_var}}
-
-{
-  "page_number": 1,
-  "page_size": 100
-}
-### 返回值解释
-### list 分页结果的实际列表数据 
-### page_number 当前页码
-### page_size 每页大小
-### total_page 总页数
-### total_row  当前分页的总数
-### total_nftt_count 符合条件的总记录数