Quellcode durchsuchen

Nftt模块的创建功能

skyfffire vor 2 Monaten
Ursprung
Commit
7feb4a8540

+ 1 - 1
src/main/java/common/interceptor/LoginInterceptor.java

@@ -13,7 +13,7 @@ public class LoginInterceptor implements Interceptor {
 
         String serverToken = (String)controller.getSession().getAttribute("dl-token");
         String clientToken = controller.getHeader("dl-token");
-        String id = controller.getSessionAttr("id");
+        String id = controller.getSessionAttr("user_id");
         String mobileNumber = controller.getSessionAttr("mobile_number");
 
         if (StrKit.notBlank(serverToken, clientToken) && clientToken.equals(serverToken) && StrKit.notBlank(id, mobileNumber)) {

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

@@ -11,6 +11,7 @@ import common.interceptor.ExceptionInterceptor;
 import common.interceptor.empty.EmptyInterceptor;
 import common.model._MappingKit;
 import modules.hello.HelloController;
+import modules.nftt.NfttController;
 import modules.upload.UploadController;
 import modules.user.UserController;
 
@@ -42,6 +43,7 @@ public class AppConfig extends JFinalConfig {
         
         routes.add("/user", UserController.class);
         routes.add("/upload", UploadController.class);
+        routes.add("/nftt", NfttController.class);
     }
 
     @Override

+ 13 - 0
src/main/java/common/model/base/BaseNftt.java

@@ -21,6 +21,19 @@ public abstract class BaseNftt<M extends BaseNftt<M>> extends Model<M> implement
 	public java.lang.Integer getId() {
 		return getInt("id");
 	}
+	/**
+	 * NFT名字
+	 */
+	public void setName(java.lang.String name) {
+		set("name", name);
+	}
+	
+	/**
+	 * NFT名字
+	 */
+	public java.lang.String getName() {
+		return getStr("name");
+	}
 	/**
 	 * 售价(¥)
 

+ 142 - 0
src/main/java/modules/nftt/NfttController.java

@@ -0,0 +1,142 @@
+package modules.nftt;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.jfinal.aop.Before;
+import com.jfinal.aop.Inject;
+import com.jfinal.kit.StrKit;
+import common.interceptor.LoginInterceptor;
+import common.interceptor.empty.EmptyInterface;
+import common.interceptor.role.RequiredRoleInterface;
+import common.model.Nftt;
+import common.utils.http.MyController;
+import common.utils.http.MyRet;
+import modules.user.UserController;
+
+import java.math.BigDecimal;
+
+public class NfttController extends MyController {
+    @Inject
+    NfttService service;
+
+    public void hello() {
+        renderJson(MyRet.ok(service.hello()));
+    }
+    
+    @Before(LoginInterceptor.class)
+    @RequiredRoleInterface({UserController.ROLE_CHECK_ADMIN, UserController.ROLE_SUPER_ADMIN})
+    @EmptyInterface({"price", "name", "presale_start_time", "presale_end_time", "buying_start_time", "author", "max_quantity", "detail_image_list"})
+    public void create() {
+        JSONObject requestBodyJson = MyController.getJsonModelByRequestAndType(getRequest(), JSONObject.class);
+
+        Nftt nftt = new Nftt(); // 创建 Model 实例
+
+        // 获取当前用户ID作为 creater_id (需要从Session或LoginInterceptor中获取)
+        // 假设你在登录成功后将用户ID存储在Session中,键名为 "user_id"
+        String currentUserIdStr = getSessionAttr("user_id");
+        if (StrKit.isBlank(currentUserIdStr)) {
+            renderJson(MyRet.fail("创建失败: 未获取到用户信息,请重新登录"));
+            return;
+        }
+        nftt.set("creater_id", new Integer(currentUserIdStr));
+
+        try {
+            // ** price (decimal) **
+            // JSON 可能是 Double、Integer 或 String,统一转为 BigDecimal
+            BigDecimal price = requestBodyJson.getBigDecimal("price");
+            if (price == null) {
+                // 虽然 EmptyInterface 确保了不为空字符串,但可能为 null
+                renderJson(MyRet.fail("售价(price)不能为空或格式不正确"));
+                return;
+            }
+            // 可以添加额外的业务校验,例如 price 必须大于 0
+            if (price.compareTo(BigDecimal.ZERO) < 0) {
+                renderJson(MyRet.fail("售价(price)不能为负数"));
+                return;
+            }
+            nftt.set("price", price);
+
+            // ** name (varchar) **
+            String name = requestBodyJson.getString("name");
+            nftt.set("name", name);
+
+            // ** presale_start_time (bigint) **
+            Long presaleStartTime = requestBodyJson.getLong("presale_start_time");
+            // 业务校验:时间戳必须是正数或非负数
+            if (presaleStartTime <= 0) {
+                renderJson(MyRet.fail("预售开始时间(presale_start_time)必须是有效的Unix时间戳"));
+                return;
+            }
+            nftt.set("presale_start_time", presaleStartTime);
+
+            // ** presale_end_time (bigint) **
+            Long presaleEndTime = requestBodyJson.getLong("presale_end_time");
+            if (presaleEndTime <= 0) {
+                renderJson(MyRet.fail("预售结束时间(presale_end_time)必须是有效的Unix时间戳"));
+                return;
+            }
+            nftt.set("presale_end_time", presaleEndTime);
+
+            // ** buying_start_time (bigint) **
+            Long buyingStartTime = requestBodyJson.getLong("buying_start_time");
+            if (buyingStartTime <= 0) {
+                renderJson(MyRet.fail("开放购买时间(buying_start_time)必须是有效的Unix时间戳"));
+                return;
+            }
+            nftt.set("buying_start_time", buyingStartTime);
+
+            // ** author (varchar) **
+            String author = requestBodyJson.getString("author");
+            nftt.set("author", author);
+
+            // ** max_quantity (int) **
+            Integer maxQuantity = requestBodyJson.getInteger("max_quantity");
+            if (maxQuantity == null || maxQuantity <= 0) {
+                renderJson(MyRet.fail("最大份数(max_quantity)必须是大于0的整数"));
+                return;
+            }
+            nftt.set("max_quantity", maxQuantity);
+
+            // ** detail_image_list (json) **
+            // 数据库字段是 JSON 类型,需要存储 JSON 字符串
+            // 获取 JSON 数组
+            JSONArray detailImageListArray = requestBodyJson.getJSONArray("detail_image_list");
+            if (detailImageListArray == null || detailImageListArray.isEmpty()) {
+                // EmptyInterface 应该已经保证了 non-null,但可能为空数组
+                // 如果图片列表不能为空,这里可以返回错误
+                renderJson(MyRet.fail("介绍图URL列表(detail_image_list)不能为空"));
+                return;
+            }
+            // 转换为 JSON 字符串存储
+            nftt.set("detail_image_list", detailImageListArray.toJSONString());
+
+            // ** purchased_quantity (int) - 默认值 **
+            // 这是一个内部字段,通常在创建时初始化为 0
+            nftt.set("purchased_quantity", 0);
+
+            // ** crate_time, update_time (bigint) - 默认时间戳 **
+            long currentTimeMillis = System.currentTimeMillis();
+            nftt.set("create_time", currentTimeMillis);
+            nftt.set("update_time", currentTimeMillis);
+
+            // ** is_deleted (int) - 默认值 **
+            nftt.set("is_deleted", 0); // 0表示未删除
+
+            // 打印 Nftt 对象内部实际存储的属性,进行调试验证
+            System.out.println("Nftt Model 的内部数据 (for debug): " + nftt);
+
+            if (service.save(nftt)) {
+                renderJson(MyRet.ok("创建成功").setData(service.findNfttById(nftt.getId())));
+            } else {
+                renderJson(MyRet.fail("创建失败,原因未知,请将此日志提供给开发者" + nftt).setData(nftt));
+            }            
+        } catch (NumberFormatException e) {
+            // 捕获可能发生的数字转换异常
+            renderJson(MyRet.fail("参数格式不正确,请检查数字或时间戳字段: " + e.getMessage()));
+        } catch (Exception e) {
+            // 捕获其他未知异常
+            renderJson(MyRet.fail("创建失败:" + e.getMessage()));
+            e.printStackTrace(); // 打印堆栈跟踪,便于调试
+        }
+    }
+}

+ 17 - 0
src/main/java/modules/nftt/NfttService.java

@@ -0,0 +1,17 @@
+package modules.nftt;
+
+import common.model.Nftt;
+
+public class NfttService {
+    public String hello() {
+        return "Hello Nftt";
+    }
+    
+    public boolean save(Nftt nftt) {
+        return nftt.save();
+    }
+    
+    public Nftt findNfttById(Integer id) {
+        return Nftt.dao.findById(id);
+    }
+}

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

@@ -6,7 +6,6 @@ import com.jfinal.aop.Inject;
 import com.jfinal.kit.HashKit;
 import com.jfinal.kit.StrKit;
 import common.interceptor.LoginInterceptor;
-import common.interceptor.empty.EmptyInterceptor;
 import common.interceptor.empty.EmptyInterface;
 import common.interceptor.role.RequiredRoleInterface;
 import common.model.User;
@@ -32,7 +31,7 @@ public class UserController extends MyController {
     private UserService service;
 
     public void hello() {
-        renderText(service.hello());
+        renderJson(MyRet.ok(service.hello()));
     }
     
     @EmptyInterface({"mobile_number"})
@@ -106,7 +105,7 @@ public class UserController extends MyController {
         // 因为 getPara("mobile_number") 已经获取了手机号,这里可以手动设置
         // 或者优化 getModel 的用法,让它只获取数据库字段,然后手动设置 mobileNumber。
         // 但为了保持原先 getModel 的语义,这里继续使用。
-        User user = getModel(User.class, "", true); // 这里不需要传入 true,因为大部分字段都是数据库字段
+        User user = getModel(User.class, "", true);
 
         // 确保 mobile_number 填充正确
         if (StrKit.isBlank(user.getStr("mobile_number"))) {
@@ -166,7 +165,7 @@ public class UserController extends MyController {
             ret.set("token", createToken("dl-token"));
 
             // 其它参数的封装
-            setSessionAttr("id", ((User)ret.get("data")).getStr("id"));
+            setSessionAttr("user_id", ((User)ret.get("data")).getStr("id"));
             setSessionAttr("mobile_number", ((User)ret.get("data")).getStr("mobile_number"));
             setSessionAttr("role", ((User)ret.get("data")).getStr("role"));
         }
@@ -190,7 +189,7 @@ public class UserController extends MyController {
     }
 
     public void logout() {
-        removeSessionAttr("id");
+        removeSessionAttr("user_id");
         removeSessionAttr("mobile_number");
         removeSessionAttr("dl-token");
         removeSessionAttr("role");

+ 43 - 0
src/test/rest/NfttControllerTest.http

@@ -0,0 +1,43 @@
+### 连通性测试
+POST {{ baseUrl }}/nftt/hello
+
+### 【审核管理员、超级管理员】NFT模板创建接口
+POST {{ baseUrl }}/nftt/create
+Content-Type: application/json
+dl-token: {{dl_token_var}}
+
+{
+  "price": 0.99,
+  "name": "张三丰真迹",
+  "presale_start_time": 1756797150932,
+  "presale_end_time": 1756797150932,
+  "buying_start_time": 1756797150932,
+  "author": "张三丰",
+  "max_quantity": 100,
+  "detail_image_list": [
+    "https://jfinal.com/upload/img/share/0/61566_20201109163639.jpg"
+  ]
+}
+
+### 【超级管理员】统计已注册用户数量,用于分页
+POST {{ baseUrl }}/nftt/update
+Content-Type: application/json
+dl-token: {{dl_token_var}}
+
+### 【超级管理员】获取用户列表,keywords当前版本支持手机号、id、昵称的模糊查询
+POST {{ baseUrl }}/nftt/nftts
+Content-Type: application/json
+dl-token: {{dl_token_var}}
+
+{
+  "page_number": 1,
+  "page_size": 100,
+  "keywords": "177"
+}
+### 返回值解释
+### list 分页结果的实际列表数据 
+### page_number 当前页码
+### page_size 每页大小
+### total_page 总页数
+### total_row  当前分页的总数
+### total_nftt_count 符合条件的总记录数

+ 3 - 0
src/test/rest/UserControllerTest.http

@@ -1,3 +1,6 @@
+### 连通性测试
+POST {{ baseUrl }}/user/hello
+
 ### 登录,可以选择传入pwd_md5(密码登录)或verify_code(验证码登录)。如果两者都传入了,后台会优先使用pwd_md5
 ### 登录成功后会返token回来,后面请求需要用户状态的接口都需要携带到headers里面,key是dl-token
 POST {{ baseUrl }}/user/login