|
|
@@ -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让上层捕获
|
|
|
+ // 如果是服务故障,可能需要全局捕获并告警
|
|
|
}
|
|
|
}
|
|
|
|