Parcourir la source

智能柜项目提交

skyline il y a 4 mois
Parent
commit
77534c3f75
63 fichiers modifiés avec 1297 ajouts et 761 suppressions
  1. 8 0
      .gitignore
  2. 6 0
      .gitignore.local
  3. 40 0
      haha-common/pom.xml
  4. 2 2
      haha-common/src/main/java/com/haha/common/vo/LoginVO.java
  5. 2 2
      haha-common/src/main/java/com/haha/common/vo/OpenDoorVO.java
  6. 2 2
      haha-common/src/main/java/com/haha/common/vo/OrderItemVO.java
  7. 2 2
      haha-common/src/main/java/com/haha/common/vo/OrderVO.java
  8. 11 11
      haha-common/src/main/java/com/haha/common/vo/RedisConstants.java
  9. 1 1
      haha-common/src/main/java/com/haha/common/vo/Result.java
  10. 2 2
      haha-common/src/main/java/com/haha/common/vo/UserVO.java
  11. 39 0
      haha-entity/pom.xml
  12. 1 1
      haha-entity/src/main/java/com/haha/entity/Account.java
  13. 1 1
      haha-entity/src/main/java/com/haha/entity/Device.java
  14. 2 2
      haha-entity/src/main/java/com/haha/entity/FundLog.java
  15. 1 1
      haha-entity/src/main/java/com/haha/entity/Order.java
  16. 1 1
      haha-entity/src/main/java/com/haha/entity/Product.java
  17. 1 1
      haha-entity/src/main/java/com/haha/entity/User.java
  18. 39 0
      haha-mapper/pom.xml
  19. 2 2
      haha-mapper/src/main/java/com/haha/mapper/AccountMapper.java
  20. 2 2
      haha-mapper/src/main/java/com/haha/mapper/DeviceMapper.java
  21. 2 2
      haha-mapper/src/main/java/com/haha/mapper/FundLogMapper.java
  22. 2 2
      haha-mapper/src/main/java/com/haha/mapper/OrderMapper.java
  23. 2 2
      haha-mapper/src/main/java/com/haha/mapper/ProductMapper.java
  24. 2 2
      haha-mapper/src/main/java/com/haha/mapper/UserMapper.java
  25. 21 53
      haha-miniapp/pom.xml
  26. 3 1
      haha-miniapp/src/main/java/com/haha/miniapp/Application.java
  27. 1 1
      haha-miniapp/src/main/java/com/haha/miniapp/config/GlobalExceptionHandler.java
  28. 2 2
      haha-miniapp/src/main/java/com/haha/miniapp/controller/CallbackController.java
  29. 22 20
      haha-miniapp/src/main/java/com/haha/miniapp/controller/DeviceController.java
  30. 3 3
      haha-miniapp/src/main/java/com/haha/miniapp/controller/LoginController.java
  31. 2 2
      haha-miniapp/src/main/java/com/haha/miniapp/controller/OrderController.java
  32. 6 6
      haha-miniapp/src/main/resources/application.yml
  33. 33 8
      haha-mp/src/pages/index/index.vue
  34. 1 1
      haha-mp/src/utils/config.ts
  35. 7 12
      haha-sdk/pom.xml
  36. 29 11
      haha-sdk/src/main/java/com/haha/sdk/HahaClient.java
  37. 2 0
      haha-sdk/src/main/java/com/haha/sdk/api/BaseApi.java
  38. 37 32
      haha-sdk/src/main/java/com/haha/sdk/api/DeviceApi.java
  39. 107 69
      haha-sdk/src/main/java/com/haha/sdk/api/GoodsApi.java
  40. 46 42
      haha-sdk/src/main/java/com/haha/sdk/api/OrderApi.java
  41. 4 4
      haha-sdk/src/main/java/com/haha/sdk/model/DeviceOnlineStatus.java
  42. 7 2
      haha-sdk/src/main/java/com/haha/sdk/model/OpenDoorResult.java
  43. 94 0
      haha-sdk/src/main/java/com/haha/sdk/util/CallbackUtils.java
  44. 20 2
      haha-sdk/src/main/java/com/haha/sdk/util/HttpUtils.java
  45. 5 1
      haha-sdk/src/main/java/com/haha/sdk/util/SignUtils.java
  46. 88 0
      haha-service/pom.xml
  47. 2 2
      haha-service/src/main/java/com/haha/service/AccountService.java
  48. 2 2
      haha-service/src/main/java/com/haha/service/DeviceService.java
  49. 1 1
      haha-service/src/main/java/com/haha/service/HahaCallbackService.java
  50. 4 4
      haha-service/src/main/java/com/haha/service/LoginService.java
  51. 2 2
      haha-service/src/main/java/com/haha/service/OrderService.java
  52. 2 2
      haha-service/src/main/java/com/haha/service/ProductService.java
  53. 3 3
      haha-service/src/main/java/com/haha/service/RedisService.java
  54. 2 2
      haha-service/src/main/java/com/haha/service/UserService.java
  55. 4 4
      haha-service/src/main/java/com/haha/service/impl/AccountServiceImpl.java
  56. 4 4
      haha-service/src/main/java/com/haha/service/impl/DeviceServiceImpl.java
  57. 3 3
      haha-service/src/main/java/com/haha/service/impl/HahaCallbackServiceImpl.java
  58. 8 8
      haha-service/src/main/java/com/haha/service/impl/LoginServiceImpl.java
  59. 4 4
      haha-service/src/main/java/com/haha/service/impl/OrderServiceImpl.java
  60. 4 4
      haha-service/src/main/java/com/haha/service/impl/ProductServiceImpl.java
  61. 5 5
      haha-service/src/main/java/com/haha/service/impl/UserServiceImpl.java
  62. 138 0
      pom.xml
  63. 396 398
      哈哈零售API详细文档.md

+ 8 - 0
.gitignore

@@ -12,3 +12,11 @@
 # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
 hs_err_pid*
 
+.idea/
+.vscode/
+haha-miniapp/target/
+haha-sdk/target/
+haha-common/target/
+haha-entity/target/
+haha-mapper/target/
+haha-service/target/

+ 6 - 0
.gitignore.local

@@ -0,0 +1,6 @@
+haha-miniapp/target/
+.idea/
+*.class
+haha-sdk/target/haha-sdk-1.0.0.jar
+haha-sdk/target/
+.vscode/

+ 40 - 0
haha-common/pom.xml

@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>com.haha</groupId>
+        <artifactId>haha-parent</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>haha-common</artifactId>
+    <name>haha-common</name>
+    <description>公共模块 - 通用工具类和响应结果类</description>
+
+    <dependencies>
+        <!-- Lombok -->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+
+        <!-- FastJson -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+        </dependency>
+
+        <!-- Spring Web (用于HTTP相关工具) -->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-web</artifactId>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+</project>

+ 2 - 2
haha-miniapp/src/main/java/com/haha/miniapp/vo/LoginVO.java → haha-common/src/main/java/com/haha/common/vo/LoginVO.java

@@ -1,10 +1,10 @@
-package com.haha.miniapp.vo;
+package com.haha.common.vo;
 
 import lombok.Builder;
 import lombok.Data;
 
 /**
- * 登录结果展示对象
+ * 鐧诲綍缁撴灉灞曠ず瀵硅薄
  */
 @Data
 @Builder

+ 2 - 2
haha-miniapp/src/main/java/com/haha/miniapp/vo/OpenDoorVO.java → haha-common/src/main/java/com/haha/common/vo/OpenDoorVO.java

@@ -1,10 +1,10 @@
-package com.haha.miniapp.vo;
+package com.haha.common.vo;
 
 import lombok.Builder;
 import lombok.Data;
 
 /**
- * 开门结果展示对象
+ * 寮€闂ㄧ粨鏋滃睍绀哄璞?
  */
 @Data
 @Builder

+ 2 - 2
haha-miniapp/src/main/java/com/haha/miniapp/vo/OrderItemVO.java → haha-common/src/main/java/com/haha/common/vo/OrderItemVO.java

@@ -1,9 +1,9 @@
-package com.haha.miniapp.vo;
+package com.haha.common.vo;
 
 import lombok.Data;
 
 /**
- * 订单商品展示对象
+ * 璁㈠崟鍟嗗搧灞曠ず瀵硅薄
  */
 @Data
 public class OrderItemVO {

+ 2 - 2
haha-miniapp/src/main/java/com/haha/miniapp/vo/OrderVO.java → haha-common/src/main/java/com/haha/common/vo/OrderVO.java

@@ -1,11 +1,11 @@
-package com.haha.miniapp.vo;
+package com.haha.common.vo;
 
 import lombok.Data;
 import java.time.LocalDateTime;
 import java.util.List;
 
 /**
- * 订单详情展示对象
+ * 璁㈠崟璇︽儏灞曠ず瀵硅薄
  */
 @Data
 public class OrderVO {

+ 11 - 11
haha-miniapp/src/main/java/com/haha/miniapp/common/RedisConstants.java → haha-common/src/main/java/com/haha/common/vo/RedisConstants.java

@@ -1,51 +1,51 @@
-package com.haha.miniapp.common;
+package com.haha.common;
 
 /**
- * Redis 缓存键常量类
- * 统一管理所有 Redis 缓存的键名
+ * Redis 缂撳瓨閿父閲忕被
+ * 缁熶竴绠$悊鎵€鏈?Redis 缂撳瓨鐨勯敭鍚?
  */
 public class RedisConstants {
 
     /**
-     * Sa-Token 用户会话相关
+     * Sa-Token 鐢ㄦ埛浼氳瘽鐩稿叧
      */
     public static final String SA_TOKEN_USER_KEY_PREFIX = "satoken:user:";
     public static final String SA_TOKEN_USER_LOGIN_ID_KEY = "satoken:loginId:%s";
     public static final String SA_TOKEN_USER_TOKEN_KEY = "satoken:token:%s";
 
     /**
-     * 设备状态相关
+     * 璁惧鐘舵€佺浉鍏?
      */
     public static final String DEVICE_STATUS_KEY_PREFIX = "device_status:";
     public static final String DEVICE_STATUS_KEY = "device_status:%s";
 
     /**
-     * 分布式锁相关
+     * 鍒嗗竷寮忛攣鐩稿叧
      */
     public static final String LOCK_DOOR_KEY_PREFIX = "lock:door:";
     public static final String LOCK_DOOR_KEY = "lock:door:%s";
 
     /**
-     * 临时订单相关
+     * 涓存椂璁㈠崟鐩稿叧
      */
     public static final String ORDER_TEMP_KEY_PREFIX = "order:temp:";
     public static final String ORDER_TEMP_KEY = "order:temp:%s";
 
     /**
-     * 用户信息缓存相关
+     * 鐢ㄦ埛淇℃伅缂撳瓨鐩稿叧
      */
     public static final String USER_INFO_KEY_PREFIX = "user:info:";
     public static final String USER_INFO_KEY = "user:info:%s";
 
     /**
-     * 商品信息缓存相关
+     * 鍟嗗搧淇℃伅缂撳瓨鐩稿叧
      */
     public static final String PRODUCT_INFO_KEY_PREFIX = "product:info:";
     public static final String PRODUCT_INFO_KEY = "product:info:%s";
 
     /**
-     * 设备信息缓存相关
+     * 璁惧淇℃伅缂撳瓨鐩稿叧
      */
     public static final String DEVICE_INFO_KEY_PREFIX = "device:info:";
     public static final String DEVICE_INFO_KEY = "device:info:%s";
-}
+}

+ 1 - 1
haha-miniapp/src/main/java/com/haha/miniapp/common/Result.java → haha-common/src/main/java/com/haha/common/vo/Result.java

@@ -1,4 +1,4 @@
-package com.haha.miniapp.common;
+package com.haha.common.vo;
 
 import lombok.Data;
 

+ 2 - 2
haha-miniapp/src/main/java/com/haha/miniapp/vo/UserVO.java → haha-common/src/main/java/com/haha/common/vo/UserVO.java

@@ -1,10 +1,10 @@
-package com.haha.miniapp.vo;
+package com.haha.common.vo;
 
 import lombok.Builder;
 import lombok.Data;
 
 /**
- * 用户信息展示对象
+ * 鐢ㄦ埛淇℃伅灞曠ず瀵硅薄
  */
 @Data
 @Builder

+ 39 - 0
haha-entity/pom.xml

@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>com.haha</groupId>
+        <artifactId>haha-parent</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>haha-entity</artifactId>
+    <name>haha-entity</name>
+    <description>实体模块 - 数据库实体类</description>
+
+    <dependencies>
+        <!-- MyBatis Plus -->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
+        </dependency>
+
+        <!-- Lombok -->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+
+        <!-- FastJson -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 1 - 1
haha-miniapp/src/main/java/com/haha/miniapp/entity/Account.java → haha-entity/src/main/java/com/haha/entity/Account.java

@@ -1,4 +1,4 @@
-package com.haha.miniapp.entity;
+package com.haha.entity;
 
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;

+ 1 - 1
haha-miniapp/src/main/java/com/haha/miniapp/entity/Device.java → haha-entity/src/main/java/com/haha/entity/Device.java

@@ -1,4 +1,4 @@
-package com.haha.miniapp.entity;
+package com.haha.entity;
 
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;

+ 2 - 2
haha-miniapp/src/main/java/com/haha/miniapp/entity/FundLog.java → haha-entity/src/main/java/com/haha/entity/FundLog.java

@@ -1,4 +1,4 @@
-package com.haha.miniapp.entity;
+package com.haha.entity;
 
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
@@ -19,7 +19,7 @@ public class FundLog implements Serializable {
     private Long userId;
 
     /**
-     * 交易类型:1-充值,2-消费,3-退款,4-提现
+     * 浜ゆ槗绫诲瀷锛?-鍏呭€硷紝2-娑堣垂锛?-閫€娆撅紝4-鎻愮幇
      */
     private Integer type;
 

+ 1 - 1
haha-miniapp/src/main/java/com/haha/miniapp/entity/Order.java → haha-entity/src/main/java/com/haha/entity/Order.java

@@ -1,4 +1,4 @@
-package com.haha.miniapp.entity;
+package com.haha.entity;
 
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;

+ 1 - 1
haha-miniapp/src/main/java/com/haha/miniapp/entity/Product.java → haha-entity/src/main/java/com/haha/entity/Product.java

@@ -1,4 +1,4 @@
-package com.haha.miniapp.entity;
+package com.haha.entity;
 
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;

+ 1 - 1
haha-miniapp/src/main/java/com/haha/miniapp/entity/User.java → haha-entity/src/main/java/com/haha/entity/User.java

@@ -1,4 +1,4 @@
-package com.haha.miniapp.entity;
+package com.haha.entity;
 
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;

+ 39 - 0
haha-mapper/pom.xml

@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>com.haha</groupId>
+        <artifactId>haha-parent</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>haha-mapper</artifactId>
+    <name>haha-mapper</name>
+    <description>数据访问模块 - MyBatis Mapper接口</description>
+
+    <dependencies>
+        <!-- 依赖实体模块 -->
+        <dependency>
+            <groupId>com.haha</groupId>
+            <artifactId>haha-entity</artifactId>
+        </dependency>
+
+        <!-- MyBatis Plus -->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
+        </dependency>
+
+        <!-- Lombok -->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+    </dependencies>
+
+</project>

+ 2 - 2
haha-miniapp/src/main/java/com/haha/miniapp/mapper/AccountMapper.java → haha-mapper/src/main/java/com/haha/mapper/AccountMapper.java

@@ -1,7 +1,7 @@
-package com.haha.miniapp.mapper;
+package com.haha.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.haha.miniapp.entity.Account;
+import com.haha.entity.Account;
 
 public interface AccountMapper extends BaseMapper<Account> {
 }

+ 2 - 2
haha-miniapp/src/main/java/com/haha/miniapp/mapper/DeviceMapper.java → haha-mapper/src/main/java/com/haha/mapper/DeviceMapper.java

@@ -1,7 +1,7 @@
-package com.haha.miniapp.mapper;
+package com.haha.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.haha.miniapp.entity.Device;
+import com.haha.entity.Device;
 
 public interface DeviceMapper extends BaseMapper<Device> {
 }

+ 2 - 2
haha-miniapp/src/main/java/com/haha/miniapp/mapper/FundLogMapper.java → haha-mapper/src/main/java/com/haha/mapper/FundLogMapper.java

@@ -1,7 +1,7 @@
-package com.haha.miniapp.mapper;
+package com.haha.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.haha.miniapp.entity.FundLog;
+import com.haha.entity.FundLog;
 
 public interface FundLogMapper extends BaseMapper<FundLog> {
 }

+ 2 - 2
haha-miniapp/src/main/java/com/haha/miniapp/mapper/OrderMapper.java → haha-mapper/src/main/java/com/haha/mapper/OrderMapper.java

@@ -1,7 +1,7 @@
-package com.haha.miniapp.mapper;
+package com.haha.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.haha.miniapp.entity.Order;
+import com.haha.entity.Order;
 
 public interface OrderMapper extends BaseMapper<Order> {
 }

+ 2 - 2
haha-miniapp/src/main/java/com/haha/miniapp/mapper/ProductMapper.java → haha-mapper/src/main/java/com/haha/mapper/ProductMapper.java

@@ -1,7 +1,7 @@
-package com.haha.miniapp.mapper;
+package com.haha.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.haha.miniapp.entity.Product;
+import com.haha.entity.Product;
 
 public interface ProductMapper extends BaseMapper<Product> {
 }

+ 2 - 2
haha-miniapp/src/main/java/com/haha/miniapp/mapper/UserMapper.java → haha-mapper/src/main/java/com/haha/mapper/UserMapper.java

@@ -1,7 +1,7 @@
-package com.haha.miniapp.mapper;
+package com.haha.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.haha.miniapp.entity.User;
+import com.haha.entity.User;
 
 public interface UserMapper extends BaseMapper<User> {
 }

+ 21 - 53
haha-miniapp/pom.xml

@@ -5,28 +5,31 @@
     <modelVersion>4.0.0</modelVersion>
 
     <parent>
-        <groupId>org.springframework.boot</groupId>
-        <artifactId>spring-boot-starter-parent</artifactId>
-        <version>3.4.13</version>
-        <relativePath/>
+        <groupId>com.haha</groupId>
+        <artifactId>haha-parent</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
     </parent>
 
     <groupId>com.haha</groupId>
     <artifactId>haha-miniapp</artifactId>
-    <version>1.0.0</version>
+    <version>0.0.1-SNAPSHOT</version>
     <name>haha-miniapp</name>
     <description>智能视觉售卖机系统 - 用户端小程序后端</description>
 
-    <properties>
-        <java.version>21</java.version>
-        <maven.compiler.source>${java.version}</maven.compiler.source>
-        <maven.compiler.target>${java.version}</maven.compiler.target>
-        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <mybatis-plus.version>3.5.10.1</mybatis-plus.version>
-        <hutool.version>5.8.28</hutool.version>
-    </properties>
+
 
     <dependencies>
+        <!-- 内部模块依赖 -->
+        <dependency>
+            <groupId>com.haha</groupId>
+            <artifactId>haha-service</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.haha</groupId>
+            <artifactId>haha-common</artifactId>
+        </dependency>
+
         <!-- Spring Boot 核心依赖 -->
         <dependency>
             <groupId>org.springframework.boot</groupId>
@@ -50,14 +53,12 @@
         <dependency>
             <groupId>com.baomidou</groupId>
             <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
-            <version>${mybatis-plus.version}</version>
         </dependency>
 
         <!-- 工具类 -->
         <dependency>
             <groupId>cn.hutool</groupId>
             <artifactId>hutool-all</artifactId>
-            <version>${hutool.version}</version>
         </dependency>
         <dependency>
             <groupId>org.projectlombok</groupId>
@@ -71,32 +72,22 @@
             <artifactId>spring-boot-starter-data-redis</artifactId>
         </dependency>
 
-        <!-- 微信支付相关 (暂时注释,后续需要时再添加) -->
-        <!-- <dependency>
-            <groupId>com.github.wechatpay-apiv3</groupId>
-            <artifactId>wechatpay-java</artifactId>
-            <version>0.2.13</version>
-        </dependency> -->
-
-        <!-- 其他工具 -->
+        <!-- FastJson -->
         <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>fastjson</artifactId>
-            <version>2.0.45</version>
         </dependency>
-        
+
         <!-- Sa-Token 认证框架 -->
         <dependency>
             <groupId>cn.dev33</groupId>
             <artifactId>sa-token-spring-boot3-starter</artifactId>
-            <version>1.39.0</version>
         </dependency>
 
-        <!-- Sa-Token 整合 RedisTemplate -->
+        <!-- Sa-Token 整合 Redis(使用 jackson 序列化) -->
         <dependency>
             <groupId>cn.dev33</groupId>
-            <artifactId>sa-token-redis-template</artifactId>
-            <version>1.44.0</version>
+            <artifactId>sa-token-redis-jackson</artifactId>
         </dependency>
 
         <!-- 提供 Redis 连接池 -->
@@ -104,29 +95,6 @@
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-pool2</artifactId>
         </dependency>
-
-        <!-- Sa-Token 整合 Redis(使用 jackson 序列化) -->
-        <dependency>
-            <groupId>cn.dev33</groupId>
-            <artifactId>sa-token-redis-jackson</artifactId>
-            <version>1.39.0</version>
-        </dependency>
-
-        <!-- 哈哈零售 SDK -->
-        <dependency>
-            <groupId>com.haha</groupId>
-            <artifactId>haha-sdk</artifactId>
-            <version>1.0.0</version>
-        </dependency>
-
-        <!-- PageHelper 分页插件 -->
-        <dependency>
-            <groupId>com.github.pagehelper</groupId>
-            <artifactId>pagehelper</artifactId>
-            <version>5.3.3</version>
-        </dependency>
-        
-
     </dependencies>
 
     <build>
@@ -138,4 +106,4 @@
         </plugins>
     </build>
 
-</project>
+</project>

+ 3 - 1
haha-miniapp/src/main/java/com/haha/miniapp/Application.java

@@ -2,6 +2,7 @@ package com.haha.miniapp;
 
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.context.annotation.Bean;
 import org.springframework.beans.BeansException;
@@ -12,7 +13,8 @@ import org.springframework.core.PriorityOrdered;
 import org.springframework.core.Ordered;
 
 @SpringBootApplication
-@MapperScan("com.haha.miniapp.mapper")
+@ComponentScan(basePackages = {"com.haha"})
+@MapperScan("com.haha.mapper")
 public class Application {
 
     @Bean

+ 1 - 1
haha-miniapp/src/main/java/com/haha/miniapp/config/GlobalExceptionHandler.java

@@ -1,7 +1,7 @@
 package com.haha.miniapp.config;
 
 import cn.dev33.satoken.exception.NotLoginException;
-import com.haha.miniapp.common.Result;
+import com.haha.common.vo.Result;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.ExceptionHandler;
 import org.springframework.web.bind.annotation.RestControllerAdvice;

+ 2 - 2
haha-miniapp/src/main/java/com/haha/miniapp/controller/CallbackController.java

@@ -4,8 +4,8 @@ import cn.dev33.satoken.annotation.SaIgnore;
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONArray;
 import com.alibaba.fastjson2.JSONObject;
-import com.haha.miniapp.entity.Order;
-import com.haha.miniapp.service.OrderService;
+import com.haha.entity.Order;
+import com.haha.service.OrderService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;

+ 22 - 20
haha-miniapp/src/main/java/com/haha/miniapp/controller/DeviceController.java

@@ -1,8 +1,8 @@
 package com.haha.miniapp.controller;
 
 import cn.dev33.satoken.stp.StpUtil;
-import com.haha.miniapp.entity.Order;
-import com.haha.miniapp.service.OrderService;
+import com.haha.entity.Order;
+import com.haha.service.OrderService;
 import com.haha.sdk.HahaClient;
 import com.haha.sdk.exception.HahaException;
 import com.haha.sdk.model.DeviceOnlineStatus;
@@ -67,37 +67,39 @@ public class DeviceController {
             // ========== 3. 检查设备在线状态 ==========
             DeviceOnlineStatus onlineStatus = hahaClient.getDeviceApi().getOnlineStatus(deviceId);
             
-            if (onlineStatus.getOnlineStatus() != 1) {
-                log.warn("设备 {} 当前离线,最后在线时间: {}", deviceId, onlineStatus.getLastOnlineTime());
+            if (onlineStatus.getIsOnline() != 1) {
+                log.warn("设备 {} 当前离线", deviceId);
                 result.put("code", 400);
                 result.put("message", "设备当前离线,请稍后再试");
                 result.put("data", Map.of(
                     "online", false,
-                    "lastOnlineTime", onlineStatus.getLastOnlineTime()
+                    "deviceId", deviceId
                 ));
                 return result;
             }
 
             // ========== 4. 检查是否多门单开 ==========
             Integer multiDoorType = hahaClient.getDeviceApi().isMultiDoorUnique(deviceId);
-            Integer doorIndex = null;
+            String doorIndex = null;
             
-            // 如果是多门单开设备,默认打开A门(索引0)
+            // 如果是多门单开设备,默认打开A门
             if (multiDoorType != null && multiDoorType > 0) {
-                doorIndex = 0; // 0-A门, 1-B门
+                doorIndex = "A"; // A门或B门
                 log.info("设备 {} 是多门单开设备,类型: {},将打开A门", deviceId, multiDoorType);
             }
 
-            // ========== 5. 生成商户订单号并开门 ==========
-            String outTradeNo = "ORDER_" + userId + "_" + System.currentTimeMillis();
+            // ========== 5. 生成商户用户编号并开门 ==========
+            String outUserId = "USER" + userId;
+            String openType = "OUT"; // OUT表示消费,IN表示上货
+            String source = "MINIAPP"; // 请求来源
             
             OpenDoorResult openResult = hahaClient.getDeviceApi()
-                .openDoor(deviceId, outTradeNo, doorIndex);
+                .openDoor(deviceId, outUserId, openType, doorIndex, source);
 
             // ========== 6. 创建本地订单记录 ==========
             Order order = new Order();
-            order.setOutTradeNo(outTradeNo);
-            order.setHahaOrderNo(openResult.getOrderNo());
+            order.setOutTradeNo(outUserId);
+            order.setHahaOrderNo(openResult.getActivityId()); // 使用活动ID作为订单号
             order.setUserId(userId);
             order.setDeviceSn(deviceId);
             order.setStatus(0); // 0-待支付(等待识别结果)
@@ -106,21 +108,21 @@ public class DeviceController {
             
             boolean saved = orderService.save(order);
             if (!saved) {
-                log.warn("订单 {} 保存失败,但开门已成功", outTradeNo);
+                log.warn("订单 {} 保存失败,但开门已成功", outUserId);
             }
             
             // ========== 7. 返回成功结果 ==========
-            log.info("开门成功 - 设备: {}, 商户订单号: {}, 哈哈订单号: {}", 
-                deviceId, outTradeNo, openResult.getOrderNo());
+            log.info("开门成功 - 设备: {}, 活动ID: {}, 哈哈用户ID: {}", 
+                deviceId, openResult.getActivityId(), openResult.getUserId());
             
             result.put("code", 200);
-            result.put("message", "开门成功");
+            result.put("message", "开门成功,请取货");
             result.put("data", Map.of(
                 "doorOpened", true,
-                "outTradeNo", outTradeNo,
-                "orderNo", openResult.getOrderNo(),
+                "activityId", openResult.getActivityId(),
+                "userId", openResult.getUserId(),
                 "deviceId", deviceId,
-                "doorIndex", doorIndex != null ? doorIndex : 0
+                "doorIndex", doorIndex != null ? doorIndex : "A"
             ));
 
         } catch (HahaException e) {

+ 3 - 3
haha-miniapp/src/main/java/com/haha/miniapp/controller/LoginController.java

@@ -2,9 +2,9 @@ package com.haha.miniapp.controller;
 
 import cn.dev33.satoken.annotation.SaIgnore;
 import cn.dev33.satoken.stp.StpUtil;
-import com.haha.miniapp.common.Result;
-import com.haha.miniapp.service.LoginService;
-import com.haha.miniapp.vo.LoginVO;
+import com.haha.common.vo.Result;
+import com.haha.service.LoginService;
+import com.haha.common.vo.LoginVO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;

+ 2 - 2
haha-miniapp/src/main/java/com/haha/miniapp/controller/OrderController.java

@@ -4,8 +4,8 @@ import cn.dev33.satoken.stp.StpUtil;
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONArray;
 import com.alibaba.fastjson2.JSONObject;
-import com.haha.miniapp.entity.Order;
-import com.haha.miniapp.service.OrderService;
+import com.haha.entity.Order;
+import com.haha.service.OrderService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;

+ 6 - 6
haha-miniapp/src/main/resources/application.yml

@@ -1,14 +1,14 @@
 spring:
   application:
     name: haha-miniapp
-  
+
   # 数据库配置
   datasource:
     url: jdbc:mysql://server.kuaiyuman.cn:3306/haha?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
     username: root
     password: KuaiyuMan/*-
     driver-class-name: com.mysql.cj.jdbc.Driver
-  
+
   # Redis 配置
   data:
     redis:
@@ -23,7 +23,7 @@ spring:
           max-wait: -1
           max-idle: 8
           min-idle: 0
-  
+
   # 数据库初始化
   sql:
     init:
@@ -54,7 +54,7 @@ pagehelper:
 
 # 服务器配置
 server:
-  port: 8080
+  port: 7070
   servlet:
     context-path: /api
 
@@ -62,11 +62,11 @@ server:
 wechat:
   # 支付配置
   pay:
-    app-id: wx8888888888888888
+    app-id: wxef6ffc2591d04b1b
     mch-id: 1888888888
     mch-key: 88888888888888888888888888888888
     v3-api-key: 88888888888888888888888888888888
-    notify-url: http://localhost:8080/api/callback/wechat/pay
+    notify-url: http://localhost:7070/api/callback/wechat/pay
   # 小程序配置
   miniapp:
     app-id: your_wechat_miniapp_appid

+ 33 - 8
haha-mp/src/pages/index/index.vue

@@ -47,16 +47,41 @@ const scanCode = () => {
       console.log('扫码结果:', res.result);
       
       // 从扫码结果中解析设备ID
-      // 假设二维码格式为: deviceId 或 JSON格式
-      let deviceId = res.result;
+      // 二维码格式: https://hh.hahabianli.com/B142977?_wxpmm0=6009000C0000
+      // 需要提取路径中的设备ID: B142977
+      let deviceId = '';
+      
       try {
-        // 尝试解析JSON格式的二维码
-        const qrData = JSON.parse(res.result);
-        if (qrData.deviceId) {
-          deviceId = qrData.deviceId;
+        // 尝试从URL中提取deviceId
+        const urlPattern = /\/([A-Z0-9]+)(\?|$)/;
+        const match = res.result.match(urlPattern);
+        
+        if (match && match[1]) {
+          deviceId = match[1];
+          console.log('提取到设备ID:', deviceId);
+        } else {
+          // 如果不是URL格式,尝试解析JSON格式
+          try {
+            const qrData = JSON.parse(res.result);
+            if (qrData.deviceId) {
+              deviceId = qrData.deviceId;
+            }
+          } catch (e) {
+            // 不是JSON格式,直接使用扫码结果作为deviceId
+            deviceId = res.result;
+          }
+        }
+        
+        if (!deviceId) {
+          throw new Error('无法解析设备ID');
         }
-      } catch (e) {
-        // 不是JSON格式,直接使用扫码结果作为deviceId
+      } catch (error) {
+        console.error('解析设备ID失败:', error);
+        uni.showToast({
+          title: '二维码格式错误',
+          icon: 'none'
+        });
+        return;
       }
       
       // 显示加载提示

+ 1 - 1
haha-mp/src/utils/config.ts

@@ -9,7 +9,7 @@ const isDevelopment = import.meta.env.DEV || false;
 export const API_CONFIG = {
   // 后端API基础URL
   baseUrl: isDevelopment 
-    ? 'http://localhost:8080/api'  // 开发环境
+    ? 'http://localhost:7070/api'  // 开发环境
     : 'https://api.yourdomain.com/api',  // 生产环境
   
   // 请求超时时间(毫秒)

+ 7 - 12
haha-sdk/pom.xml

@@ -4,21 +4,22 @@
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
 
-    <groupId>com.haha</groupId>
+    <parent>
+        <groupId>com.haha</groupId>
+        <artifactId>haha-parent</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
     <artifactId>haha-sdk</artifactId>
-    <version>1.0.0</version>
     <packaging>jar</packaging>
 
     <name>haha-sdk</name>
     <description>哈哈零售系统 Java SDK</description>
 
     <properties>
-        <maven.compiler.source>21</maven.compiler.source>
-        <maven.compiler.target>21</maven.compiler.target>
-        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <okhttp.version>4.12.0</okhttp.version>
         <fastjson2.version>2.0.53</fastjson2.version>
-        <lombok.version>1.18.30</lombok.version>
         <slf4j.version>2.0.9</slf4j.version>
     </properties>
 
@@ -41,7 +42,6 @@
         <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
-            <version>${lombok.version}</version>
             <scope>provided</scope>
         </dependency>
 
@@ -58,11 +58,6 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-compiler-plugin</artifactId>
-                <version>3.11.0</version>
-                <configuration>
-                    <source>${maven.compiler.source}</source>
-                    <target>${maven.compiler.target}</target>
-                </configuration>
             </plugin>
         </plugins>
     </build>

+ 29 - 11
haha-sdk/src/main/java/com/haha/sdk/HahaClient.java

@@ -105,15 +105,13 @@ public class HahaClient {
         try {
             // 构建请求参数
             Map<String, String> params = new HashMap<>();
-            params.put("appid", config.getAppId());
-            params.put("appsecret", config.getAppSecret());
+            params.put("app_id", config.getAppId());
+            params.put("app_secret", config.getAppSecret());
+            // 生成6位随机字符串(小写字母和数字)
+            params.put("rand_str", generateRandStr());
             
-            // 生成签名
-            String sign = SignUtils.generateSign(params, config.getAppSecret());
-            params.put("sign", sign);
-            
-            // 发送请求
-            String url = config.getApiBaseUrl() + "/login/getToken";
+            // 发送请求(token获取接口不需要签名)
+            String url = config.getApiBaseUrl() + "/token/get";
             String response = httpUtils.post(url, params);
             
             // 解析响应
@@ -127,9 +125,14 @@ public class HahaClient {
             Map<String, Object> data = (Map<String, Object>) result.get("data");
             this.accessToken = (String) data.get("access_token");
             
-            // 计算过期时间(15天 = 1296000秒)
-            Integer expiresIn = (Integer) data.get("expires_in");
-            this.tokenExpireTime = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(expiresIn);
+            // 计算过期时间,使用文档中的exprire字段(注意拼写)
+            Integer expire = (Integer) data.get("exprire");
+            if (expire != null) {
+                this.tokenExpireTime = TimeUnit.SECONDS.toMillis(expire);
+            } else {
+                // 如果没有返回过期时间,默认15天
+                this.tokenExpireTime = System.currentTimeMillis() + TimeUnit.DAYS.toMillis(15);
+            }
             
             log.info("access_token刷新成功,有效期至: {}", new java.util.Date(tokenExpireTime));
             
@@ -139,6 +142,21 @@ public class HahaClient {
         }
     }
     
+    /**
+     * 生成6位随机字符串(小写字母和数字)
+     * 
+     * @return 随机字符串
+     */
+    private String generateRandStr() {
+        String chars = "abcdefghijklmnopqrstuvwxyz0123456789";
+        StringBuilder sb = new StringBuilder(6);
+        for (int i = 0; i < 6; i++) {
+            int index = (int) (Math.random() * chars.length());
+            sb.append(chars.charAt(index));
+        }
+        return sb.toString();
+    }
+    
     /**
      * 手动设置访问令牌
      * 如果商户自行管理令牌,可通过此方法设置

+ 2 - 0
haha-sdk/src/main/java/com/haha/sdk/api/BaseApi.java

@@ -26,6 +26,8 @@ public abstract class BaseApi {
     
     /**
      * POST请求
+     * 注意:主动调用哈哈平台的API接口不需要签名
+     * 签名机制仅用于回调通知接口的验证
      * 
      * @param path API路径
      * @param params 请求参数

+ 37 - 32
haha-sdk/src/main/java/com/haha/sdk/api/DeviceApi.java

@@ -65,25 +65,32 @@ public class DeviceApi extends BaseApi {
      * 设备开门
      * 
      * @param deviceId 设备ID
-     * @param outTradeNo 商户订单号
-     * @param doorIndex 门编号(0或不传表示A门,1表示B门),多门单开设备必传
+     * @param outUserId 商户系统用户编号(非哈哈系统产生),6-32位数字或字母
+     * @param openType 开门类型:IN 表示上货,OUT 表示消费
+     * @param doorIndex 门编号:A 左门,B 右门,双门单开柜该参数必传
+     * @param source 请求来源(可选)
      * @return 开门结果
      * @throws HahaException 调用失败时抛出
      */
-    public OpenDoorResult openDoor(String deviceId, String outTradeNo, Integer doorIndex) throws HahaException {
+    public OpenDoorResult openDoor(String deviceId, String outUserId, String openType, String doorIndex, String source) throws HahaException {
         Map<String, String> params = new HashMap<>();
         params.put("access_token", client.getAccessToken());
         params.put("device_id", deviceId);
-        params.put("out_trade_no", outTradeNo);
-        if (doorIndex != null) {
-            params.put("door_index", String.valueOf(doorIndex));
+        params.put("out_user_id", outUserId);
+        params.put("open_type", openType);
+        if (doorIndex != null && !doorIndex.isEmpty()) {
+            params.put("door_index", doorIndex);
+        }
+        if (source != null && !source.isEmpty()) {
+            params.put("source", source);
         }
         
-        Map<String, Object> result = post("/device/open", params);
+        Map<String, Object> result = post("/door/open", params);
         Object data = result.get("data");
         if (data instanceof Map) {
             OpenDoorResult openResult = new OpenDoorResult();
-            openResult.setOrderNo((String) ((Map<?, ?>) data).get("order_no"));
+            openResult.setActivityId((String) ((Map<?, ?>) data).get("activity_id"));
+            openResult.setUserId((String) ((Map<?, ?>) data).get("user_id"));
             return openResult;
         }
         throw new HahaException("开门失败:返回数据格式错误");
@@ -101,36 +108,36 @@ public class DeviceApi extends BaseApi {
         params.put("access_token", client.getAccessToken());
         params.put("device_id", deviceId);
         
-        Map<String, Object> result = post("/device/onlineStatus", params);
+        Map<String, Object> result = post("/device/getDeviceOnlineStatus", params);
         Object data = result.get("data");
         if (data instanceof Map) {
             DeviceOnlineStatus status = new DeviceOnlineStatus();
-            status.setOnlineStatus((Integer) ((Map<?, ?>) data).get("online_status"));
-            status.setLastOnlineTime((String) ((Map<?, ?>) data).get("last_online_time"));
+            status.setDeviceId((String) ((Map<?, ?>) data).get("device_id"));
+            status.setIsOnline(Integer.valueOf((String) ((Map<?, ?>) data).get("is_online")));
             return status;
         }
         throw new HahaException("查询设备在线状态失败:返回数据格式错误");
     }
     
     /**
-     * 设置设备音量
+     * 设置设备音量(仅限动态柜)
      * 
      * @param deviceId 设备ID
-     * @param volume 音量值:0-100,0表示静音,100表示最大音量
+     * @param voice 音量大小值 0~15
      * @return 是否成功
      * @throws HahaException 调用失败时抛出
      */
-    public boolean setVolume(String deviceId, int volume) throws HahaException {
-        if (volume < 0 || volume > 100) {
-            throw new IllegalArgumentException("音量值必须在0-100之间");
+    public boolean setVoice(String deviceId, int voice) throws HahaException {
+        if (voice < 0 || voice > 15) {
+            throw new IllegalArgumentException("音量值必须在0-15之间");
         }
         
         Map<String, String> params = new HashMap<>();
         params.put("access_token", client.getAccessToken());
         params.put("device_id", deviceId);
-        params.put("volume", String.valueOf(volume));
+        params.put("voice", String.valueOf(voice));
         
-        post("/device/setVolume", params);
+        post("/device/voiceControl", params);
         return true;
     }
     
@@ -146,7 +153,7 @@ public class DeviceApi extends BaseApi {
         params.put("access_token", client.getAccessToken());
         params.put("device_id", deviceId);
         
-        Map<String, Object> result = post("/device/status", params);
+        Map<String, Object> result = post("/device/checkstatus", params);
         Object data = result.get("data");
         if (data instanceof Map) {
             return (Map<String, Object>) data;
@@ -156,22 +163,20 @@ public class DeviceApi extends BaseApi {
     
     /**
      * 刷卡开门验证
-     * 用于刷卡设备,验证用户刷卡信息是否有效
+     * 由API商家提供给哈哈刷卡开门时调用
+     * 注意:这是一个由商户提供的接口,不是调用哈哈的接口
      * 
-     * @param deviceId 设备ID
-     * @param cardNo 卡号
-     * @param cardType 卡类型:1-IC卡,2-身份证,3-其他
+     * @param cardNo 卡id
+     * @param machineNo 设备编号
+     * @param timestamp 请求时间戳(毫秒)
+     * @param sign 请求参数签名
      * @return 验证结果
      * @throws HahaException 调用失败时抛出
      */
-    public Map<String, Object> cardVerify(String deviceId, String cardNo, int cardType) throws HahaException {
-        Map<String, String> params = new HashMap<>();
-        params.put("access_token", client.getAccessToken());
-        params.put("device_id", deviceId);
-        params.put("card_no", cardNo);
-        params.put("card_type", String.valueOf(cardType));
-        
-        Map<String, Object> result = post("/device/cardVerify", params);
-        return (Map<String, Object>) result.get("data");
+    @Deprecated
+    public Map<String, Object> cardVerify(String cardNo, String machineNo, String timestamp, String sign) throws HahaException {
+        // 注意:这个接口是由商户提供给哈哈调用的,不是商户调用哈哈的
+        // 此方法不应该在SDK中实现,标记为已废弃
+        throw new HahaException("此接口由商户提供给哈哈调用,不需要在SDK中实现");
     }
 }

+ 107 - 69
haha-sdk/src/main/java/com/haha/sdk/api/GoodsApi.java

@@ -25,20 +25,20 @@ public class GoodsApi extends BaseApi {
      * 获取设备可售卖商品列表
      * 
      * @param deviceId 设备ID
+     * @param code 商品code(可选)
      * @return 商品列表
      * @throws HahaException 调用失败时抛出
      */
-    public List<Map<String, Object>> getDeviceGoodsList(String deviceId) throws HahaException {
+    public Map<String, Object> getDeviceGoodsList(String deviceId, String code) throws HahaException {
         Map<String, String> params = new HashMap<>();
         params.put("access_token", client.getAccessToken());
         params.put("device_id", deviceId);
-        
-        Map<String, Object> result = post("/goods/deviceGoodsList", params);
-        Object data = result.get("data");
-        if (data instanceof List) {
-            return (List<Map<String, Object>>) data;
+        if (code != null && !code.isEmpty()) {
+            params.put("code", code);
         }
-        return null;
+        
+        Map<String, Object> result = post("/product/getProductsListByDeviceId", params);
+        return (Map<String, Object>) result.get("data");
     }
     
     /**
@@ -46,38 +46,49 @@ public class GoodsApi extends BaseApi {
      * 
      * @param pageNo 页码
      * @param pageSize 每页条数
-     * @param keyword 搜索关键词(可选)
+     * @param barcode 条形码,多个条形码用逗号隔开(可选)
+     * @param code 商品code,多个商品code用逗号隔开(可选)
+     * @param productName 商品名称(可选)
+     * @param deviceAdapt 适应设备(可选)
      * @return 商品总库信息
      * @throws HahaException 调用失败时抛出
      */
-    public Map<String, Object> getTotalList(int pageNo, int pageSize, String keyword) throws HahaException {
+    public Map<String, Object> getTotalList(int pageNo, int pageSize, String barcode, String code, 
+                                            String productName, String deviceAdapt) throws HahaException {
         Map<String, String> params = new HashMap<>();
         params.put("access_token", client.getAccessToken());
         params.put("page_no", String.valueOf(pageNo));
         params.put("page_size", String.valueOf(pageSize));
-        if (keyword != null && !keyword.isEmpty()) {
-            params.put("keyword", keyword);
+        if (barcode != null && !barcode.isEmpty()) {
+            params.put("barcode", barcode);
+        }
+        if (code != null && !code.isEmpty()) {
+            params.put("code", code);
+        }
+        if (productName != null && !productName.isEmpty()) {
+            params.put("product_name", productName);
+        }
+        if (deviceAdapt != null && !deviceAdapt.isEmpty()) {
+            params.put("device_adapt", deviceAdapt);
         }
         
-        Map<String, Object> result = post("/goods/totalList", params);
+        Map<String, Object> result = post("/product/getAssignedProducts", params);
         return (Map<String, Object>) result.get("data");
     }
     
     /**
      * 添加商品至商家商品库
      * 
-     * @param goodsId 商品ID(来自商品总库)
-     * @param price 售价
+     * @param codeList 商品列表(传入哈哈的商品编码,多个中间用逗号隔开)
      * @return 是否成功
      * @throws HahaException 调用失败时抛出
      */
-    public boolean addToMerchant(String goodsId, String price) throws HahaException {
+    public boolean addToMerchant(String codeList) throws HahaException {
         Map<String, String> params = new HashMap<>();
         params.put("access_token", client.getAccessToken());
-        params.put("goods_id", goodsId);
-        params.put("price", price);
+        params.put("code_list", codeList);
         
-        post("/goods/addToMerchant", params);
+        post("/Product/addClientProducts", params);
         return true;
     }
     
@@ -86,37 +97,60 @@ public class GoodsApi extends BaseApi {
      * 
      * @param pageNo 页码
      * @param pageSize 每页条数
+     * @param name 商品名称(可选)
+     * @param barCode 商品条码(可选)
+     * @param applyStatus 适用设备:1全部柜,2静态柜,3动态柜(可选)
+     * @param code 商品编码(可选)
      * @return 商家商品库信息
      * @throws HahaException 调用失败时抛出
      */
-    public Map<String, Object> getMerchantList(int pageNo, int pageSize) throws HahaException {
+    public Map<String, Object> getMerchantList(int pageNo, int pageSize, String name, 
+                                                String barCode, String applyStatus, String code) throws HahaException {
         Map<String, String> params = new HashMap<>();
         params.put("access_token", client.getAccessToken());
         params.put("page_no", String.valueOf(pageNo));
         params.put("page_size", String.valueOf(pageSize));
+        if (name != null && !name.isEmpty()) {
+            params.put("name", name);
+        }
+        if (barCode != null && !barCode.isEmpty()) {
+            params.put("bar_code", barCode);
+        }
+        if (applyStatus != null && !applyStatus.isEmpty()) {
+            params.put("apply_status", applyStatus);
+        }
+        if (code != null && !code.isEmpty()) {
+            params.put("code", code);
+        }
         
-        Map<String, Object> result = post("/goods/merchantList", params);
+        Map<String, Object> result = post("/product/getClientProducts", params);
         return (Map<String, Object>) result.get("data");
     }
     
     /**
-     * 设置商品上下架状态
+     * 商品上下架
      * 
-     * @param deviceId 设备ID
-     * @param goodsId 商品ID
-     * @param status 状态:0-下架,1-上架
+     * @param deviceId 设备id,sn号
+     * @param goodsCode 商品code,多个商品code用逗号(,)隔开
+     * @param salesType 上下架类型:IN上架,OUT下架。call_type='CHANGE'时必传。
+     * @param callType 请求更新方式:CHANGE更新模式,COVER覆盖模式,不传默认值是CHANGE。
      * @return 是否成功
      * @throws HahaException 调用失败时抛出
      */
-    public boolean setStatus(String deviceId, String goodsId, int status) throws HahaException {
+    public Map<String, Object> setStatus(String deviceId, String goodsCode, String salesType, String callType) throws HahaException {
         Map<String, String> params = new HashMap<>();
         params.put("access_token", client.getAccessToken());
         params.put("device_id", deviceId);
-        params.put("goods_id", goodsId);
-        params.put("status", String.valueOf(status));
+        params.put("goods_code", goodsCode);
+        if (salesType != null && !salesType.isEmpty()) {
+            params.put("sales_type", salesType);
+        }
+        if (callType != null && !callType.isEmpty()) {
+            params.put("call_type", callType);
+        }
         
-        post("/goods/setStatus", params);
-        return true;
+        Map<String, Object> result = post("/systemtemplate/deviceGoods", params);
+        return (Map<String, Object>) result.get("data");
     }
     
     /**
@@ -132,7 +166,7 @@ public class GoodsApi extends BaseApi {
         params.put("access_token", client.getAccessToken());
         params.put("device_id", deviceId);
         
-        Map<String, Object> result = post("/goods/getLayerTemplate", params);
+        Map<String, Object> result = post("/product/getLayerTypeInfo", params);
         return (Map<String, Object>) result.get("data");
     }
     
@@ -141,84 +175,88 @@ public class GoodsApi extends BaseApi {
      * 创建或更新设备的货架层级模板
      * 
      * @param deviceId 设备ID
-     * @param layers 层级配置数组(JSON格式)
+     * @param products 层模板商品数据(json)
      * @return 是否成功
      * @throws HahaException 调用失败时抛出
      */
-    public boolean updateLayerTemplate(String deviceId, String layers) throws HahaException {
+    public Map<String, Object> updateLayerTemplate(String deviceId, String products) throws HahaException {
         Map<String, String> params = new HashMap<>();
         params.put("access_token", client.getAccessToken());
         params.put("device_id", deviceId);
-        params.put("layers", layers);
+        params.put("products", products);
         
-        post("/goods/updateLayerTemplate", params);
-        return true;
+        Map<String, Object> result = post("/product/postLayerTypeInfo", params);
+        return (Map<String, Object>) result.get("data");
     }
     
     /**
      * 新品申请
      * 商家申请添加新商品到哈哈平台商品总库
      * 
-     * @param goodsName 商品名称
-     * @param barcode 商品条码
-     * @param image 商品图片URL
-     * @param description 商品描述(可选)
-     * @return 是否成功
+     * @param params 新品申请参数,详见API文档
+     * @return 新品申请工单编号
      * @throws HahaException 调用失败时抛出
      */
-    public boolean applyNew(String goodsName, String barcode, String image, String description) throws HahaException {
-        Map<String, String> params = new HashMap<>();
+    public Map<String, Object> applyNew(Map<String, String> params) throws HahaException {
         params.put("access_token", client.getAccessToken());
-        params.put("goods_name", goodsName);
-        params.put("barcode", barcode);
-        params.put("image", image);
-        if (description != null && !description.isEmpty()) {
-            params.put("description", description);
-        }
         
-        post("/goods/applyNew", params);
-        return true;
+        Map<String, Object> result = post("/goods/addClientNewGoodsInfo", params);
+        return (Map<String, Object>) result.get("data");
     }
     
     /**
      * 查询商品编号对应关系
      * 查询商家商品ID与哈哈平台商品ID的对应关系
      * 
-     * @param merchantGoodsId 商家商品ID(可选)
-     * @param hahaGoodsId 哈哈平台商品ID(可选)
+     * @param codeList 哈哈商品编号列表,多个用逗号隔开(可选)
      * @return 对应关系信息
      * @throws HahaException 调用失败时抛出
      */
-    public Map<String, Object> getIdMapping(String merchantGoodsId, String hahaGoodsId) throws HahaException {
+    public Map<String, Object> getIdMapping(String codeList) throws HahaException {
         Map<String, String> params = new HashMap<>();
         params.put("access_token", client.getAccessToken());
-        if (merchantGoodsId != null && !merchantGoodsId.isEmpty()) {
-            params.put("merchant_goods_id", merchantGoodsId);
-        }
-        if (hahaGoodsId != null && !hahaGoodsId.isEmpty()) {
-            params.put("haha_goods_id", hahaGoodsId);
+        if (codeList != null && !codeList.isEmpty()) {
+            params.put("code_list", codeList);
         }
         
-        Map<String, Object> result = post("/goods/idMapping", params);
+        Map<String, Object> result = post("/product/getProductsRelation", params);
         return (Map<String, Object>) result.get("data");
     }
     
     /**
-     * 商品合并
-     * 将多个相似商品合并为一个商品
+     * 上传图片
+     * 用于新品申请时上传商品图片
      * 
-     * @param targetGoodsId 目标商品ID(保留的商品)
-     * @param sourceGoodsIds 源商品ID数组(将被合并的商品),多个ID用逗号分隔
-     * @return 是否成功
+     * @param file 图片文件
+     * @return 图片地址
      * @throws HahaException 调用失败时抛出
      */
-    public boolean mergeGoods(String targetGoodsId, String sourceGoodsIds) throws HahaException {
+    public String uploadImage(java.io.File file) throws HahaException {
+        // 注意:这个接口需要multipart/form-data格式,需要特殊处理
+        // 该方法需要在HttpUtils中添加文件上传支持
+        throw new HahaException("文件上传功能尚未实现,请使用img_type=url方式");
+    }
+    
+    /**
+     * 查看新品申请
+     * 获取新品申请商品信息
+     * 
+     * @param code 商品code(可选)
+     * @param id 新品申请主键id(可选)
+     * @return 新品申请信息
+     * @throws HahaException 调用失败时抛出
+     */
+    public Map<String, Object> getNewGoodsInfo(String code, String id) throws HahaException {
         Map<String, String> params = new HashMap<>();
         params.put("access_token", client.getAccessToken());
-        params.put("target_goods_id", targetGoodsId);
-        params.put("source_goods_ids", sourceGoodsIds);
+        if (code != null && !code.isEmpty()) {
+            params.put("code", code);
+        }
+        if (id != null && !id.isEmpty()) {
+            params.put("id", id);
+        }
         
-        post("/goods/merge", params);
-        return true;
+        Map<String, Object> result = post("/goods/getNewClientGoodsInfo", params);
+        return (Map<String, Object>) result.get("data");
     }
 }

+ 46 - 42
haha-sdk/src/main/java/com/haha/sdk/api/OrderApi.java

@@ -23,86 +23,82 @@ public class OrderApi extends BaseApi {
     /**
      * 查询识别结果
      * 
-     * @param orderNo 哈哈平台订单号(与outTradeNo二选一)
-     * @param outTradeNo 商户订单号(与orderNo二选一)
+     * @param orderId 订单编号(与activityId二选一)
+     * @param activityId 活动编号(与orderId二选一)
      * @return 识别结果
      * @throws HahaException 调用失败时抛出
      */
-    public Map<String, Object> getRecognizeResult(String orderNo, String outTradeNo) throws HahaException {
+    public Map<String, Object> getRecognizeResult(String orderId, String activityId) throws HahaException {
         Map<String, String> params = new HashMap<>();
         params.put("access_token", client.getAccessToken());
-        if (orderNo != null && !orderNo.isEmpty()) {
-            params.put("order_no", orderNo);
+        if (orderId != null && !orderId.isEmpty()) {
+            params.put("order_id", orderId);
         }
-        if (outTradeNo != null && !outTradeNo.isEmpty()) {
-            params.put("out_trade_no", outTradeNo);
+        if (activityId != null && !activityId.isEmpty()) {
+            params.put("activity_id", activityId);
         }
         
-        Map<String, Object> result = post("/order/recognizeResult", params);
+        Map<String, Object> result = post("/order/recResult", params);
         return (Map<String, Object>) result.get("data");
     }
     
     /**
      * 查询订单详情
      * 
-     * @param orderNo 哈哈平台订单号(与outTradeNo二选一)
-     * @param outTradeNo 商户订单号(与orderNo二选一)
+     * @param orderId 订单编号(与activityId二选一)
+     * @param activityId 活动编号(与orderId二选一)
      * @return 订单详情
      * @throws HahaException 调用失败时抛出
      */
-    public Map<String, Object> queryOrder(String orderNo, String outTradeNo) throws HahaException {
+    public Map<String, Object> queryOrder(String orderId, String activityId) throws HahaException {
         Map<String, String> params = new HashMap<>();
         params.put("access_token", client.getAccessToken());
-        if (orderNo != null && !orderNo.isEmpty()) {
-            params.put("order_no", orderNo);
+        if (orderId != null && !orderId.isEmpty()) {
+            params.put("order_id", orderId);
         }
-        if (outTradeNo != null && !outTradeNo.isEmpty()) {
-            params.put("out_trade_no", outTradeNo);
+        if (activityId != null && !activityId.isEmpty()) {
+            params.put("activity_id", activityId);
         }
         
-        Map<String, Object> result = post("/order/query", params);
+        Map<String, Object> result = post("/order/getOrderInfo", params);
         return (Map<String, Object>) result.get("data");
     }
     
     /**
      * 设置订单支付状态
      * 
-     * @param orderNo 哈哈平台订单号
-     * @param payStatus 支付状态:1-支付成功,2-支付失败
-     * @param payTime 支付时间(可选)
-     * @param transactionId 第三方支付流水号(可选)
+     * @param orderId 哈哈平台订单号
      * @return 是否成功
      * @throws HahaException 调用失败时抛出
      */
-    public boolean setPayStatus(String orderNo, int payStatus, String payTime, String transactionId) throws HahaException {
+    public boolean setPayStatus(String orderId) throws HahaException {
         Map<String, String> params = new HashMap<>();
         params.put("access_token", client.getAccessToken());
-        params.put("order_no", orderNo);
-        params.put("pay_status", String.valueOf(payStatus));
-        if (payTime != null && !payTime.isEmpty()) {
-            params.put("pay_time", payTime);
-        }
-        if (transactionId != null && !transactionId.isEmpty()) {
-            params.put("transaction_id", transactionId);
-        }
+        params.put("order_id", orderId);
         
-        post("/order/setPayStatus", params);
+        post("/order/setOrderStatus", params);
         return true;
     }
     
     /**
      * 获取开门前后图片或视频
      * 
-     * @param orderNo 哈哈平台订单号
+     * @param orderId 订单编号(与activityId二选一)
+     * @param activityId 活动编号(与orderId二选一)
      * @return 媒体文件信息
      * @throws HahaException 调用失败时抛出
      */
-    public Map<String, Object> getOrderMedia(String orderNo) throws HahaException {
+    public Map<String, Object> getOrderMedia(String orderId, String activityId) throws HahaException {
         Map<String, String> params = new HashMap<>();
         params.put("access_token", client.getAccessToken());
-        params.put("order_no", orderNo);
+        if (orderId != null && !orderId.isEmpty()) {
+            params.put("order_id", orderId);
+        }
+        if (activityId != null && !activityId.isEmpty()) {
+            params.put("activity_id", activityId);
+        }
         
-        Map<String, Object> result = post("/order/media", params);
+        Map<String, Object> result = post("/order/getorderspic", params);
         return (Map<String, Object>) result.get("data");
     }
     
@@ -110,16 +106,18 @@ public class OrderApi extends BaseApi {
      * 查询识别或订单回调结果
      * 查询哈哈平台是否成功推送识别结果或订单通知给商户
      * 
-     * @param orderNo 哈哈平台订单号
+     * @param type 识别类型: REC识别结果回调,ORDER 订单结果回调
+     * @param actId 活动编号
      * @return 回调状态信息
      * @throws HahaException 调用失败时抛出
      */
-    public Map<String, Object> getCallbackStatus(String orderNo) throws HahaException {
+    public Map<String, Object> getCallbackInfo(String type, String actId) throws HahaException {
         Map<String, String> params = new HashMap<>();
         params.put("access_token", client.getAccessToken());
-        params.put("order_no", orderNo);
+        params.put("type", type);
+        params.put("act_id", actId);
         
-        Map<String, Object> result = post("/order/callbackStatus", params);
+        Map<String, Object> result = post("/order/getCallbackInfo", params);
         return (Map<String, Object>) result.get("data");
     }
     
@@ -127,16 +125,22 @@ public class OrderApi extends BaseApi {
      * 获取静态柜分层图片与识别结果
      * 获取静态货柜的分层图片和每层的识别结果(适用于静态识别柜)
      * 
-     * @param orderNo 哈哈平台订单号
+     * @param orderId 订单编号(与activityId二选一)
+     * @param activityId 活动编号(与orderId二选一)
      * @return 分层识别结果
      * @throws HahaException 调用失败时抛出
      */
-    public Map<String, Object> getLayerRecognize(String orderNo) throws HahaException {
+    public Map<String, Object> getLayerRecognize(String orderId, String activityId) throws HahaException {
         Map<String, String> params = new HashMap<>();
         params.put("access_token", client.getAccessToken());
-        params.put("order_no", orderNo);
+        if (orderId != null && !orderId.isEmpty()) {
+            params.put("order_id", orderId);
+        }
+        if (activityId != null && !activityId.isEmpty()) {
+            params.put("activity_id", activityId);
+        }
         
-        Map<String, Object> result = post("/order/layerRecognize", params);
+        Map<String, Object> result = post("/order/recResultLayers", params);
         return (Map<String, Object>) result.get("data");
     }
 }

+ 4 - 4
haha-sdk/src/main/java/com/haha/sdk/model/DeviceOnlineStatus.java

@@ -12,12 +12,12 @@ import lombok.Data;
 public class DeviceOnlineStatus {
     
     /**
-     * 在线状态:0-离线,1-在线
+     * 设备编号
      */
-    private Integer onlineStatus;
+    private String deviceId;
     
     /**
-     * 最后在线时间
+     * 在线状态:0-离线,1-在线
      */
-    private String lastOnlineTime;
+    private Integer isOnline;
 }

+ 7 - 2
haha-sdk/src/main/java/com/haha/sdk/model/OpenDoorResult.java

@@ -12,7 +12,12 @@ import lombok.Data;
 public class OpenDoorResult {
     
     /**
-     * 哈哈平台订单号
+     * 选购活动ID
      */
-    private String orderNo;
+    private String activityId;
+    
+    /**
+     * 哈哈便利用户ID
+     */
+    private String userId;
 }

+ 94 - 0
haha-sdk/src/main/java/com/haha/sdk/util/CallbackUtils.java

@@ -0,0 +1,94 @@
+package com.haha.sdk.util;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * 回调工具类
+ * 用于处理哈哈平台的回调通知
+ * 
+ * 重要说明:
+ * 1. 哈哈平台的签名机制仅用于回调通知的验证
+ * 2. 商户主动调用哈哈平台的API接口时不需要签名
+ * 3. 回调通知使用ticket进行验签(ticket从/token/get接口获取)
+ * 
+ * @author haha-sdk
+ * @version 1.0.0
+ */
+public class CallbackUtils {
+    
+    /**
+     * 验证回调签名
+     * 
+     * @param params 回调参数(包含sign字段)
+     * @param ticket 票据(从token获取接口返回的ticket字段)
+     * @return 签名是否正确
+     */
+    public static boolean verifySign(Map<String, String> params, String ticket) {
+        if (params == null || !params.containsKey("sign")) {
+            return false;
+        }
+        
+        String receivedSign = params.get("sign");
+        
+        // 使用TreeMap自动按key排序
+        TreeMap<String, String> sortedParams = new TreeMap<>(params);
+        
+        // 拼接参数(排除sign字段)
+        StringBuilder sb = new StringBuilder();
+        for (Map.Entry<String, String> entry : sortedParams.entrySet()) {
+            if ("sign".equals(entry.getKey())) {
+                continue;
+            }
+            if (sb.length() > 0) {
+                sb.append("&");
+            }
+            sb.append(entry.getKey()).append("=").append(entry.getValue());
+        }
+        
+        // 拼接ticket
+        sb.append("&ticket=").append(ticket);
+        
+        // MD5加密生成签名
+        String calculatedSign = SignUtils.md5(sb.toString());
+        
+        // 比较签名
+        return calculatedSign.equals(receivedSign);
+    }
+    
+    /**
+     * 获取回调通知类型
+     * 
+     * @param params 回调参数
+     * @return 通知类型
+     */
+    public static String getNotifyType(Map<String, String> params) {
+        return params.get("notify_type");
+    }
+    
+    /**
+     * 回调通知类型枚举
+     */
+    public static class NotifyType {
+        /** 设备状态通知(开关门) */
+        public static final String DEVICE_STATUS = "DEVICE_STATUS";
+        /** 设备在线状态通知 */
+        public static final String ONLINE_STATUS = "ONLINE_STATUS";
+        /** 设备音量调节结果通知 */
+        public static final String VOICE_RESULT = "VOICE_RESULT";
+        /** 新品审核结果通知 */
+        public static final String CLIENT_NEW_PRODUCT = "CLIENT_NEW_PRODUCT";
+        /** 商品合并结果通知 */
+        public static final String MERGE_PRODUCT = "MERGE_PRODUCT";
+        /** AI识别结果通知(最重要) */
+        public static final String ORC_RESULT = "ORC_RESULT";
+    }
+    
+    /**
+     * 回调响应常量
+     */
+    public static class Response {
+        /** 成功响应 */
+        public static final String SUCCESS = "success";
+    }
+}

+ 20 - 2
haha-sdk/src/main/java/com/haha/sdk/util/HttpUtils.java

@@ -61,15 +61,24 @@ public class HttpUtils {
         
         Request request = new Request.Builder()
                 .url(url)
+                .header("Content-Type", "application/x-www-form-urlencoded")
                 .post(builder.build())
                 .build();
         
+        log.debug("POST请求URL: {}", url);
+        log.debug("POST请求参数: {}", params);
+        
         try (Response response = client.newCall(request).execute()) {
+            log.debug("POST响应状态: {}", response.code());
+            log.debug("POST响应头: {}", response.headers());
+            
             if (!response.isSuccessful()) {
                 throw new IOException("HTTP请求失败: " + response.code());
             }
             ResponseBody body = response.body();
-            return body != null ? body.string() : "";
+            String responseBody = body != null ? body.string() : "";
+            log.debug("POST响应体: {}", responseBody);
+            return responseBody;
         }
     }
     
@@ -85,15 +94,24 @@ public class HttpUtils {
         RequestBody body = RequestBody.create(jsonBody, JSON_TYPE);
         Request request = new Request.Builder()
                 .url(url)
+                .header("Content-Type", "application/json")
                 .post(body)
                 .build();
         
+        log.debug("POST JSON请求URL: {}", url);
+        log.debug("POST JSON请求体: {}", jsonBody);
+        
         try (Response response = client.newCall(request).execute()) {
+            log.debug("POST JSON响应状态: {}", response.code());
+            log.debug("POST JSON响应头: {}", response.headers());
+            
             if (!response.isSuccessful()) {
                 throw new IOException("HTTP请求失败: " + response.code());
             }
             ResponseBody responseBody = response.body();
-            return responseBody != null ? responseBody.string() : "";
+            String responseBodyStr = responseBody != null ? responseBody.string() : "";
+            log.debug("POST JSON响应体: {}", responseBodyStr);
+            return responseBodyStr;
         }
     }
     

+ 5 - 1
haha-sdk/src/main/java/com/haha/sdk/util/SignUtils.java

@@ -8,7 +8,11 @@ import java.util.TreeMap;
 
 /**
  * 签名工具类
- * 用于生成API请求签名
+ * 
+ * 重要说明:
+ * 1. 主动调用哈哈平台的API接口(如开门、查询等)不需要签名
+ * 2. 签名机制仅用于验证哈哈平台发送的回调通知(如开关门通知、识别结果通知等)
+ * 3. 回调通知使用ticket进行验签,而非使用AppSecret
  * 
  * @author haha-sdk
  * @version 1.0.0

+ 88 - 0
haha-service/pom.xml

@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>com.haha</groupId>
+        <artifactId>haha-parent</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>haha-service</artifactId>
+    <name>haha-service</name>
+    <description>业务服务模块 - Service接口和实现</description>
+
+    <dependencies>
+        <!-- 依赖Mapper模块 -->
+        <dependency>
+            <groupId>com.haha</groupId>
+            <artifactId>haha-mapper</artifactId>
+        </dependency>
+
+        <!-- 依赖公共模块 -->
+        <dependency>
+            <groupId>com.haha</groupId>
+            <artifactId>haha-common</artifactId>
+        </dependency>
+
+        <!-- 依赖哈哈SDK -->
+        <dependency>
+            <groupId>com.haha</groupId>
+            <artifactId>haha-sdk</artifactId>
+        </dependency>
+
+        <!-- Spring Boot Web -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+        <!-- MyBatis Plus -->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
+        </dependency>
+
+        <!-- Sa-Token -->
+        <dependency>
+            <groupId>cn.dev33</groupId>
+            <artifactId>sa-token-spring-boot3-starter</artifactId>
+        </dependency>
+
+        <!-- Hutool 工具包 -->
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+        </dependency>
+
+        <!-- Spring Data Redis -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+
+        <!-- FastJson -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+        </dependency>
+
+        <!-- PageHelper -->
+        <dependency>
+            <groupId>com.github.pagehelper</groupId>
+            <artifactId>pagehelper</artifactId>
+        </dependency>
+
+        <!-- Lombok -->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+    </dependencies>
+
+</project>

+ 2 - 2
haha-miniapp/src/main/java/com/haha/miniapp/service/AccountService.java → haha-service/src/main/java/com/haha/service/AccountService.java

@@ -1,7 +1,7 @@
-package com.haha.miniapp.service;
+package com.haha.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
-import com.haha.miniapp.entity.Account;
+import com.haha.entity.Account;
 import java.math.BigDecimal;
 
 public interface AccountService extends IService<Account> {

+ 2 - 2
haha-miniapp/src/main/java/com/haha/miniapp/service/DeviceService.java → haha-service/src/main/java/com/haha/service/DeviceService.java

@@ -1,7 +1,7 @@
-package com.haha.miniapp.service;
+package com.haha.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
-import com.haha.miniapp.entity.Device;
+import com.haha.entity.Device;
 import java.util.List;
 
 public interface DeviceService extends IService<Device> {

+ 1 - 1
haha-miniapp/src/main/java/com/haha/miniapp/service/HahaCallbackService.java → haha-service/src/main/java/com/haha/service/HahaCallbackService.java

@@ -1,4 +1,4 @@
-package com.haha.miniapp.service;
+package com.haha.service;
 
 import java.util.Map;
 

+ 4 - 4
haha-miniapp/src/main/java/com/haha/miniapp/service/LoginService.java → haha-service/src/main/java/com/haha/service/LoginService.java

@@ -1,7 +1,7 @@
-package com.haha.miniapp.service;
+package com.haha.service;
 
-import com.haha.miniapp.common.Result;
-import com.haha.miniapp.vo.LoginVO;
+import com.haha.common.vo.Result;
+import com.haha.common.vo.LoginVO;
 
 import java.util.Map;
 
@@ -30,4 +30,4 @@ public interface LoginService {
      * @return 用户信息
      */
     Result<Map<String, Object>> getUserInfo(String userId);
-}
+}

+ 2 - 2
haha-miniapp/src/main/java/com/haha/miniapp/service/OrderService.java → haha-service/src/main/java/com/haha/service/OrderService.java

@@ -1,7 +1,7 @@
-package com.haha.miniapp.service;
+package com.haha.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
-import com.haha.miniapp.entity.Order;
+import com.haha.entity.Order;
 import java.util.List;
 
 public interface OrderService extends IService<Order> {

+ 2 - 2
haha-miniapp/src/main/java/com/haha/miniapp/service/ProductService.java → haha-service/src/main/java/com/haha/service/ProductService.java

@@ -1,7 +1,7 @@
-package com.haha.miniapp.service;
+package com.haha.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
-import com.haha.miniapp.entity.Product;
+import com.haha.entity.Product;
 import java.util.List;
 
 public interface ProductService extends IService<Product> {

+ 3 - 3
haha-miniapp/src/main/java/com/haha/miniapp/service/RedisService.java → haha-service/src/main/java/com/haha/service/RedisService.java

@@ -1,6 +1,6 @@
-package com.haha.miniapp.service;
+package com.haha.service;
 
-import com.haha.miniapp.common.RedisConstants;
+import com.haha.common.vo.RedisConstants;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.stereotype.Service;
@@ -93,4 +93,4 @@ public class RedisService {
             String.format(RedisConstants.USER_INFO_KEY, userId)
         );
     }
-}
+}

+ 2 - 2
haha-miniapp/src/main/java/com/haha/miniapp/service/UserService.java → haha-service/src/main/java/com/haha/service/UserService.java

@@ -1,7 +1,7 @@
-package com.haha.miniapp.service;
+package com.haha.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
-import com.haha.miniapp.entity.User;
+import com.haha.entity.User;
 import java.math.BigDecimal;
 
 public interface UserService extends IService<User> {

+ 4 - 4
haha-miniapp/src/main/java/com/haha/miniapp/service/impl/AccountServiceImpl.java → haha-service/src/main/java/com/haha/service/impl/AccountServiceImpl.java

@@ -1,9 +1,9 @@
-package com.haha.miniapp.service.impl;
+package com.haha.service.impl;
 
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.haha.miniapp.entity.Account;
-import com.haha.miniapp.mapper.AccountMapper;
-import com.haha.miniapp.service.AccountService;
+import com.haha.entity.Account;
+import com.haha.mapper.AccountMapper;
+import com.haha.service.AccountService;
 import org.springframework.stereotype.Service;
 import java.math.BigDecimal;
 

+ 4 - 4
haha-miniapp/src/main/java/com/haha/miniapp/service/impl/DeviceServiceImpl.java → haha-service/src/main/java/com/haha/service/impl/DeviceServiceImpl.java

@@ -1,9 +1,9 @@
-package com.haha.miniapp.service.impl;
+package com.haha.service.impl;
 
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.haha.miniapp.entity.Device;
-import com.haha.miniapp.mapper.DeviceMapper;
-import com.haha.miniapp.service.DeviceService;
+import com.haha.entity.Device;
+import com.haha.mapper.DeviceMapper;
+import com.haha.service.DeviceService;
 import org.springframework.stereotype.Service;
 
 import java.util.List;

+ 3 - 3
haha-miniapp/src/main/java/com/haha/miniapp/service/impl/HahaCallbackServiceImpl.java → haha-service/src/main/java/com/haha/service/impl/HahaCallbackServiceImpl.java

@@ -1,10 +1,10 @@
-package com.haha.miniapp.service.impl;
+package com.haha.service.impl;
 
 import com.alibaba.fastjson2.JSON;
 import com.alibaba.fastjson2.JSONArray;
 import com.alibaba.fastjson2.JSONObject;
-import com.haha.miniapp.service.HahaCallbackService;
-import com.haha.miniapp.service.OrderService;
+import com.haha.service.HahaCallbackService;
+import com.haha.service.OrderService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;

+ 8 - 8
haha-miniapp/src/main/java/com/haha/miniapp/service/impl/LoginServiceImpl.java → haha-service/src/main/java/com/haha/service/impl/LoginServiceImpl.java

@@ -1,12 +1,12 @@
-package com.haha.miniapp.service.impl;
+package com.haha.service.impl;
 
 import cn.dev33.satoken.stp.StpUtil;
-import com.haha.miniapp.common.Result;
-import com.haha.miniapp.entity.User;
-import com.haha.miniapp.service.LoginService;
-import com.haha.miniapp.service.UserService;
-import com.haha.miniapp.vo.LoginVO;
-import com.haha.miniapp.vo.UserVO;
+import com.haha.common.vo.Result;
+import com.haha.entity.User;
+import com.haha.service.LoginService;
+import com.haha.service.UserService;
+import com.haha.common.vo.LoginVO;
+import com.haha.common.vo.UserVO;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -135,4 +135,4 @@ public class LoginServiceImpl implements LoginService {
             return Result.error(500, "获取用户信息失败:" + e.getMessage());
         }
     }
-}
+}

+ 4 - 4
haha-miniapp/src/main/java/com/haha/miniapp/service/impl/OrderServiceImpl.java → haha-service/src/main/java/com/haha/service/impl/OrderServiceImpl.java

@@ -1,9 +1,9 @@
-package com.haha.miniapp.service.impl;
+package com.haha.service.impl;
 
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.haha.miniapp.entity.Order;
-import com.haha.miniapp.mapper.OrderMapper;
-import com.haha.miniapp.service.OrderService;
+import com.haha.entity.Order;
+import com.haha.mapper.OrderMapper;
+import com.haha.service.OrderService;
 import org.springframework.stereotype.Service;
 
 import java.util.List;

+ 4 - 4
haha-miniapp/src/main/java/com/haha/miniapp/service/impl/ProductServiceImpl.java → haha-service/src/main/java/com/haha/service/impl/ProductServiceImpl.java

@@ -1,9 +1,9 @@
-package com.haha.miniapp.service.impl;
+package com.haha.service.impl;
 
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.haha.miniapp.entity.Product;
-import com.haha.miniapp.mapper.ProductMapper;
-import com.haha.miniapp.service.ProductService;
+import com.haha.entity.Product;
+import com.haha.mapper.ProductMapper;
+import com.haha.service.ProductService;
 import org.springframework.stereotype.Service;
 
 import java.util.List;

+ 5 - 5
haha-miniapp/src/main/java/com/haha/miniapp/service/impl/UserServiceImpl.java → haha-service/src/main/java/com/haha/service/impl/UserServiceImpl.java

@@ -1,10 +1,10 @@
-package com.haha.miniapp.service.impl;
+package com.haha.service.impl;
 
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.haha.miniapp.entity.User;
-import com.haha.miniapp.mapper.UserMapper;
-import com.haha.miniapp.service.UserService;
-import com.haha.miniapp.service.AccountService;
+import com.haha.entity.User;
+import com.haha.mapper.UserMapper;
+import com.haha.service.UserService;
+import com.haha.service.AccountService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import java.math.BigDecimal;

+ 138 - 0
pom.xml

@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.haha</groupId>
+    <artifactId>haha-parent</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <packaging>pom</packaging>
+    <name>haha-parent</name>
+    <description>AI智能视觉售卖机系统</description>
+
+    <modules>
+        <module>haha-common</module>
+        <module>haha-entity</module>
+        <module>haha-mapper</module>
+        <module>haha-service</module>
+        <module>haha-miniapp</module>
+        <module>haha-sdk</module>
+    </modules>
+
+    <properties>
+        <java.version>21</java.version>
+        <maven.compiler.source>${java.version}</maven.compiler.source>
+        <maven.compiler.target>${java.version}</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <spring-boot.version>3.4.13</spring-boot.version>
+        <mybatis-plus.version>3.5.10.1</mybatis-plus.version>
+        <hutool.version>5.8.28</hutool.version>
+        <satoken.version>1.39.0</satoken.version>
+        <fastjson.version>2.0.45</fastjson.version>
+        <pagehelper.version>5.3.3</pagehelper.version>
+    </properties>
+
+    <dependencyManagement>
+        <dependencies>
+            <!-- Spring Boot 依赖管理 -->
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-dependencies</artifactId>
+                <version>${spring-boot.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+
+            <!-- MyBatis Plus -->
+            <dependency>
+                <groupId>com.baomidou</groupId>
+                <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
+                <version>${mybatis-plus.version}</version>
+            </dependency>
+
+            <!-- Hutool 工具包 -->
+            <dependency>
+                <groupId>cn.hutool</groupId>
+                <artifactId>hutool-all</artifactId>
+                <version>${hutool.version}</version>
+            </dependency>
+
+            <!-- FastJson -->
+            <dependency>
+                <groupId>com.alibaba</groupId>
+                <artifactId>fastjson</artifactId>
+                <version>${fastjson.version}</version>
+            </dependency>
+
+            <!-- Sa-Token -->
+            <dependency>
+                <groupId>cn.dev33</groupId>
+                <artifactId>sa-token-spring-boot3-starter</artifactId>
+                <version>${satoken.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>cn.dev33</groupId>
+                <artifactId>sa-token-redis-jackson</artifactId>
+                <version>${satoken.version}</version>
+            </dependency>
+
+            <!-- PageHelper -->
+            <dependency>
+                <groupId>com.github.pagehelper</groupId>
+                <artifactId>pagehelper</artifactId>
+                <version>${pagehelper.version}</version>
+            </dependency>
+
+            <!-- 内部模块 -->
+            <dependency>
+                <groupId>com.haha</groupId>
+                <artifactId>haha-common</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.haha</groupId>
+                <artifactId>haha-entity</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.haha</groupId>
+                <artifactId>haha-mapper</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.haha</groupId>
+                <artifactId>haha-service</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.haha</groupId>
+                <artifactId>haha-sdk</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-maven-plugin</artifactId>
+                    <version>${spring-boot.version}</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-compiler-plugin</artifactId>
+                    <version>3.11.0</version>
+                    <configuration>
+                        <source>${java.version}</source>
+                        <target>${java.version}</target>
+                        <encoding>${project.build.sourceEncoding}</encoding>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+
+</project>

Fichier diff supprimé car celui-ci est trop grand
+ 396 - 398
哈哈零售API详细文档.md


Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff