소스 검색

后端controller中业务逻辑抽至service

skyline 1 개월 전
부모
커밋
61c71cbdb1
23개의 변경된 파일548개의 추가작업 그리고 428개의 파일을 삭제
  1. 0 20
      haha-miniapp/src/main/java/com/haha/miniapp/config/SaTokenSetupConfig.java
  2. 1 9
      haha-miniapp/src/main/java/com/haha/miniapp/controller/AppCouponController.java
  3. 3 74
      haha-miniapp/src/main/java/com/haha/miniapp/controller/DeviceController.java
  4. 10 125
      haha-miniapp/src/main/java/com/haha/miniapp/controller/InviteController.java
  5. 0 7
      haha-miniapp/src/main/java/com/haha/miniapp/controller/LoginController.java
  6. 5 38
      haha-miniapp/src/main/java/com/haha/miniapp/controller/OrderController.java
  7. 23 81
      haha-miniapp/src/main/java/com/haha/miniapp/controller/PayScoreController.java
  8. 9 69
      haha-miniapp/src/main/java/com/haha/miniapp/controller/PaymentController.java
  9. 8 0
      haha-service/src/main/java/com/haha/service/CouponTemplateService.java
  10. 9 0
      haha-service/src/main/java/com/haha/service/DeviceService.java
  11. 45 0
      haha-service/src/main/java/com/haha/service/InviteActivityService.java
  12. 9 0
      haha-service/src/main/java/com/haha/service/LayerTemplateService.java
  13. 27 0
      haha-service/src/main/java/com/haha/service/OrderService.java
  14. 13 0
      haha-service/src/main/java/com/haha/service/impl/CouponTemplateServiceImpl.java
  15. 27 0
      haha-service/src/main/java/com/haha/service/impl/DeviceServiceImpl.java
  16. 64 0
      haha-service/src/main/java/com/haha/service/impl/InviteActivityServiceImpl.java
  17. 46 0
      haha-service/src/main/java/com/haha/service/impl/LayerTemplateServiceImpl.java
  18. 37 0
      haha-service/src/main/java/com/haha/service/impl/OrderServiceImpl.java
  19. 2 4
      haha-service/src/main/java/com/haha/service/impl/UserCouponServiceImpl.java
  20. 20 0
      haha-service/src/main/java/com/haha/service/payment/PaymentService.java
  21. 78 1
      haha-service/src/main/java/com/haha/service/payment/impl/PaymentServiceImpl.java
  22. 36 0
      haha-service/src/main/java/com/haha/service/payment/payscore/PayScoreService.java
  23. 76 0
      haha-service/src/main/java/com/haha/service/payment/payscore/impl/PayScoreServiceImpl.java

+ 0 - 20
haha-miniapp/src/main/java/com/haha/miniapp/config/SaTokenSetupConfig.java

@@ -1,20 +0,0 @@
-package com.haha.miniapp.config;
-
-import cn.dev33.satoken.SaManager;
-import org.springframework.context.annotation.Configuration;
-
-import jakarta.annotation.PostConstruct;
-
-/**
- * Sa-Token 初始化配置
- * 确保Sa-Token配置正确加载
- */
-@Configuration
-public class SaTokenSetupConfig {
-
-    @PostConstruct
-    public void initSaToken() {
-        // 输出Sa-Token版本等信息,用于确认配置生效
-        System.out.println("Sa-Token 配置已加载,当前配置超时时间为:" + SaManager.getConfig().getTimeout() + " 秒");
-    }
-}

+ 1 - 9
haha-miniapp/src/main/java/com/haha/miniapp/controller/AppCouponController.java

@@ -29,15 +29,7 @@ public class AppCouponController {
     public Result<List<CouponTemplate>> getAvailableCoupons() {
         Long userId = StpUtil.getLoginIdAsLong();
         log.info("[优惠券] 查询可领取优惠券列表 - userId: {}", userId);
-        List<CouponTemplate> templates = templateService.getAvailableTemplates();
-        
-        // 填充用户已领取状态
-        templates.forEach(template -> {
-            int receivedCount = userCouponService.countReceivedByUser(userId, template.getId());
-            template.setAlreadyReceived(receivedCount > 0);
-        });
-        
-        log.info("[优惠券] 可领取优惠券数量: {}", templates.size());
+        List<CouponTemplate> templates = templateService.getAvailableTemplatesWithStatus(userId);
         return Result.success("查询成功", templates);
     }
 

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

@@ -1,13 +1,9 @@
 package com.haha.miniapp.controller;
 
 import cn.dev33.satoken.stp.StpUtil;
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.ObjectMapper;
 import com.haha.common.constant.ResponseEnum;
-import com.haha.common.dto.FloorConfig;
 import com.haha.common.vo.OpenDoorVO;
 import com.haha.common.vo.Result;
-import com.haha.entity.LayerTemplate;
 import com.haha.service.DeviceService;
 import com.haha.service.LayerTemplateService;
 import com.haha.sdk.exception.HahaException;
@@ -15,8 +11,6 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 
 /**
@@ -32,8 +26,6 @@ public class DeviceController {
     private final DeviceService deviceService;
     private final LayerTemplateService layerTemplateService;
 
-    private final ObjectMapper objectMapper = new ObjectMapper();
-
     /**
      * 处理小程序扫码开门
      *
@@ -88,81 +80,18 @@ public class DeviceController {
     @GetMapping("/products/{deviceId}")
     public Result<Map<String, Object>> getDeviceProducts(@PathVariable String deviceId) {
         try {
-            // 查询设备层模板(无需登录,允许未登录用户查看柜内商品)
-            LayerTemplate template = layerTemplateService.getByDeviceId(deviceId);
-            if (template == null) {
+            Map<String, Object> result = layerTemplateService.getDeviceProducts(deviceId);
+            if (result == null) {
                 return ResponseEnum.DEVICE_NO_PRODUCTS.toResult();
             }
-
-            // 3. 解析层数据
-            Map<String, Object> result = new HashMap<>();
-            result.put("templateName", template.getTemplateName());
-            result.put("deviceId", template.getDeviceId());
-            result.put("shelfNum", template.getShelfNum());
-            result.put("deviceType", template.getDeviceType());
-
-            // 解析左门层数据
-            if (template.getLeftFloors() != null && !template.getLeftFloors().isEmpty()) {
-                try {
-                    List<FloorConfig> leftFloors = objectMapper.readValue(
-                        template.getLeftFloors(), new TypeReference<List<FloorConfig>>() {});
-                    result.put("leftFloors", leftFloors);
-                } catch (Exception e) {
-                    log.warn("解析左门层数据失败, deviceId={}", deviceId, e);
-                    result.put("leftFloors", List.of());
-                }
-            } else {
-                result.put("leftFloors", List.of());
-            }
-
-            // 解析右门层数据
-            if (template.getRightFloors() != null && !template.getRightFloors().isEmpty()) {
-                try {
-                    List<FloorConfig> rightFloors = objectMapper.readValue(
-                        template.getRightFloors(), new TypeReference<List<FloorConfig>>() {});
-                    result.put("rightFloors", rightFloors);
-                } catch (Exception e) {
-                    log.warn("解析右门层数据失败, deviceId={}", deviceId, e);
-                    result.put("rightFloors", List.of());
-                }
-            } else {
-                result.put("rightFloors", List.of());
-            }
-
             return Result.success("查询成功", result);
-
         } catch (Exception e) {
             log.error("查询设备商品信息异常, deviceId={}", deviceId, e);
             return Result.error(500, "查询失败,请稍后重试");
         }
     }
 
-    /**
-     * 根据错误码返回友好的错误信息
-     */
     private String getErrorMessage(Integer errorCode, String defaultMsg) {
-        if (errorCode == null) {
-            return defaultMsg != null ? defaultMsg : "操作失败";
-        }
-        
-        switch (errorCode) {
-            case -1:
-                return "参数错误,请检查设备ID是否正确";
-            case -2:
-                return "签名错误,请联系技术支持";
-            case -3:
-            case -4:
-                return "认证失败,请稍后重试";
-            case -100:
-                return "设备不存在,请确认设备ID";
-            case -101:
-                return "设备离线,请稍后再试";
-            case -102:
-                return "设备故障,请联系设备维护人员";
-            case -103:
-                return "设备使用中,请稍后再试";
-            default:
-                return defaultMsg != null ? defaultMsg : "开门失败";
-        }
+        return deviceService.getHahaErrorMessage(errorCode, defaultMsg);
     }
 }

+ 10 - 125
haha-miniapp/src/main/java/com/haha/miniapp/controller/InviteController.java

@@ -12,7 +12,6 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.HashMap;
 import java.util.Map;
 
 /**
@@ -27,52 +26,19 @@ public class InviteController {
 
     private final InviteActivityService inviteActivityService;
 
-    /**
-     * 获取当前用户的邀请码和链接
-     *
-     * 业务流程:
-     * 1. 获取当前登录用户ID
-     * 2. 查询当前进行中的邀请活动
-     * 3. 为该用户生成专属邀请码
-     * 4. 返回邀请码、邀请链接及活动信息
-     *
-     * @return 包含邀请码、邀请链接、活动信息的Map
-     */
     @GetMapping("/code")
     public Result<Map<String, Object>> getInviteCode() {
         Long userId = StpUtil.getLoginIdAsLong();
         log.info("[邀请] 用户请求邀请码 - userId: {}", userId);
-
-        InviteActivity ongoingActivity = inviteActivityService.getOngoingActivity();
-        if (ongoingActivity == null) {
+        Map<String, Object> result = inviteActivityService.getInviteCodeInfo(userId);
+        if (result == null) {
             log.info("[邀请] 当前无进行中的邀请活动 - userId: {}", userId);
             return Result.error("暂无进行中的邀请活动");
         }
-
-        String inviteCode = inviteActivityService.generateInviteCode(userId, ongoingActivity.getId());
-
-        Map<String, Object> result = new HashMap<>();
-        result.put("inviteCode", inviteCode);
-        result.put("inviteLink", "pages/index/index?inviteCode=" + inviteCode);
-        result.put("activityInfo", ongoingActivity);
-
-        log.info("[邀请] 生成邀请码成功 - userId: {}, activityId: {}, inviteCode: {}",
-                userId, ongoingActivity.getId(), inviteCode);
+        log.info("[邀请] 生成邀请码成功 - userId: {}, inviteCode: {}", userId, result.get("inviteCode"));
         return Result.success("查询成功", result);
     }
 
-    /**
-     * 绑定邀请关系(新用户注册时调用)
-     *
-     * 业务流程:
-     * 1. 获取新注册用户的ID
-     * 2. 解析邀请码获取活动ID和邀请人信息
-     * 3. 建立邀请人与被邀请人的绑定关系
-     * 4. 记录来源渠道、设备信息等用于防刷检查
-     *
-     * @param params 包含 inviteCode(必填)、sourceChannel(可选)、deviceInfo(可选)
-     * @return 操作结果
-     */
     @PostMapping("/bind")
     public Result<Boolean> bindInviteRelation(@RequestBody Map<String, Object> params) {
         Long userId = StpUtil.getLoginIdAsLong();
@@ -88,97 +54,35 @@ public class InviteController {
         log.info("[邀请] 绑定邀请关系 - userId: {}, inviteCode: {}, sourceChannel: {}",
                 userId, inviteCode, sourceChannel);
 
-        // 通过邀请码查询对应的邀请记录,获取活动ID和邀请人ID
-        InviteRecord record = inviteActivityService.getInviteRecordByCode(inviteCode);
-
-        if (record == null) {
-            log.warn("[邀请] 邀请码无效或已过期 - userId: {}, inviteCode: {}", userId, inviteCode);
-            return ResponseEnum.PARAM_FORMAT_ERROR.toResult("邀请码无效或已过期");
-        }
-
-        boolean success = inviteActivityService.bindInviteRelation(
-                record.getActivityId(),
-                record.getInviterUserId(),
-                userId,
-                inviteCode,
-                sourceChannel,
-                deviceInfo,
-                ""  // IP地址由服务端获取
-        );
-
+        boolean success = inviteActivityService.bindInviteRelation(userId, inviteCode, sourceChannel, deviceInfo);
         if (!success) {
             return Result.error("绑定邀请关系失败");
         }
 
-        log.info("[邀请] 绑定邀请关系成功 - userId: {}, inviterUserId: {}, inviteCode: {}",
-                userId, record.getInviterUserId(), inviteCode);
+        log.info("[邀请] 绑定邀请关系成功 - userId: {}, inviteCode: {}", userId, inviteCode);
         return Result.success("绑定成功", true);
     }
 
-    /**
-     * 获取我的邀请记录列表
-     *
-     * 业务流程:
-     * 1. 获取当前登录用户ID
-     * 2. 查询当前进行中的邀请活动
-     * 3. 分页查询该用户作为邀请人的所有邀请记录
-     *
-     * @param page     页码(默认1)
-     * @param pageSize 每页条数(默认10)
-     * @return 分页的邀请记录列表
-     */
     @GetMapping("/my-records")
     public Result<PageResult<InviteRecord>> getMyInviteRecords(
             @RequestParam(defaultValue = "1") Integer page,
             @RequestParam(defaultValue = "10") Integer pageSize) {
         Long userId = StpUtil.getLoginIdAsLong();
         log.info("[邀请] 查询我的邀请记录 - userId: {}, page: {}, pageSize: {}", userId, page, pageSize);
-
-        InviteActivity ongoingActivity = inviteActivityService.getOngoingActivity();
-        if (ongoingActivity == null) {
-            log.info("[邀请] 当前无进行中的邀请活动,返回空数据 - userId: {}", userId);
-            return Result.success("查询成功", new PageResult<>());
-        }
-
-        IPage<InviteRecord> records = inviteActivityService.getMyInviteRecords(
-                userId, ongoingActivity.getId(), page, pageSize);
-
+        IPage<InviteRecord> records = inviteActivityService.getMyInviteRecords(userId, page, pageSize);
         log.info("[邀请] 我的邀请记录查询完成 - userId: {}, total: {}", userId, records.getTotal());
         return Result.success("查询成功", PageResult.of(records));
     }
 
-    /**
-     * 获取我的邀请统计数据
-     *
-     * 业务流程:
-     * 1. 获取当前登录用户ID
-     * 2. 查询当前进行中的邀请活动
-     * 3. 统计该用户的邀请数据(总邀请数、有效邀请数、今日邀请数等)
-     *
-     * @return 用户邀请统计数据
-     */
     @GetMapping("/my-statistics")
     public Result<Map<String, Object>> getMyInviteStatistics() {
         Long userId = StpUtil.getLoginIdAsLong();
         log.info("[邀请] 查询我的邀请统计 - userId: {}", userId);
-
-        InviteActivity ongoingActivity = inviteActivityService.getOngoingActivity();
-        if (ongoingActivity == null) {
-            log.info("[邀请] 当前无进行中的邀请活动,返回空数据 - userId: {}", userId);
-            return Result.success("查询成功", new HashMap<>());
-        }
-
-        Map<String, Object> statistics = inviteActivityService.getMyInviteStatistics(userId, ongoingActivity.getId());
-
+        Map<String, Object> statistics = inviteActivityService.getMyInviteStatistics(userId);
         log.info("[邀请] 我的邀请统计数据 - userId: {}, statistics: {}", userId, statistics);
         return Result.success("查询成功", statistics);
     }
 
-    /**
-     * 获取当前有效的邀请活动信息
-     *
-     * @return 进行中的邀请活动信息,若无则返回null
-     */
     @GetMapping("/activity-info")
     public Result<InviteActivity> getActivityInfo() {
         log.info("[邀请] 查询当前邀请活动信息");
@@ -186,35 +90,16 @@ public class InviteController {
         return Result.success("查询成功", activity);
     }
 
-    /**
-     * 生成邀请海报
-     *
-     * 业务流程:
-     * 1. 获取当前登录用户ID
-     * 2. 查询当前进行中的邀请活动
-     * 3. 生成该用户的专属邀请码
-     * 4. 返回海报相关数据(后续可接入Canvas绘制或第三方海报生成服务)
-     *
-     * @return 包含邀请码和海报URL的Map
-     */
     @GetMapping("/poster")
     public Result<Map<String, Object>> generatePoster() {
         Long userId = StpUtil.getLoginIdAsLong();
         log.info("[邀请] 生成邀请海报 - userId: {}", userId);
-
-        InviteActivity ongoingActivity = inviteActivityService.getOngoingActivity();
-        if (ongoingActivity == null) {
+        Map<String, Object> result = inviteActivityService.generatePosterInfo(userId);
+        if (result == null) {
             log.info("[邀请] 当前无进行中的邀请活动 - userId: {}", userId);
             return Result.error("暂无进行中的邀请活动");
         }
-
-        String inviteCode = inviteActivityService.generateInviteCode(userId, ongoingActivity.getId());
-
-        Map<String, Object> result = new HashMap<>();
-        result.put("inviteCode", inviteCode);
-        result.put("posterUrl", "");
-
-        log.info("[邀请] 生成邀请海报成功 - userId: {}, inviteCode: {}", userId, inviteCode);
+        log.info("[邀请] 生成邀请海报成功 - userId: {}, inviteCode: {}", userId, result.get("inviteCode"));
         return Result.success("查询成功", result);
     }
 }

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

@@ -89,11 +89,4 @@ public class LoginController {
         log.debug("[登录] 获取用户信息 - userId: {}", userId);
         return loginService.getUserInfo(userId.toString());
     }
-    
-    private String maskPhone(String phone) {
-        if (phone == null || phone.length() < 7) {
-            return phone;
-        }
-        return phone.substring(0, 3) + "****" + phone.substring(phone.length() - 4);
-    }
 }

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

@@ -29,14 +29,7 @@ public class OrderController {
     public Result<List<Map<String, Object>>> getOrderList(@RequestBody(required = false) Map<String, Object> params) {
         Long userId = StpUtil.getLoginIdAsLong();
         log.info("用户 {} 请求订单列表", userId);
-
-        Integer status = null;
-        if (params != null && params.containsKey("status")) {
-            status = Integer.valueOf(params.get("status").toString());
-        }
-
-        List<Map<String, Object>> orderList = orderService.getUserOrderListWithProducts(userId, status);
-
+        List<Map<String, Object>> orderList = orderService.getUserOrderListWithProducts(userId, params);
         log.info("用户 {} 查询到 {} 条订单", userId, orderList.size());
         return Result.success("查询成功", orderList);
     }
@@ -47,29 +40,10 @@ public class OrderController {
     @PostMapping("/detail")
     public Result<Map<String, Object>> getOrderDetail(@RequestBody Map<String, Object> params) {
         Long userId = StpUtil.getLoginIdAsLong();
-
-        Long orderId = null;
-        String orderNo = null;
-        String outTradeNo = null;
-
-        if (params.containsKey("orderId")) {
-            orderId = Long.valueOf(params.get("orderId").toString());
-            log.info("用户 {} 通过订单ID {} 查询订单详情", userId, orderId);
-        } else if (params.containsKey("orderNo")) {
-            orderNo = params.get("orderNo").toString();
-            log.info("用户 {} 通过订单号 {} 查询订单详情", userId, orderNo);
-        } else if (params.containsKey("outTradeNo")) {
-            outTradeNo = params.get("outTradeNo").toString();
-            log.info("用户 {} 通过商户订单号 {} 查询订单详情", userId, outTradeNo);
-        } else {
-            return ResponseEnum.PARAM_REQUIRED.toResult("参数错误:必须提供 orderId、orderNo 或 outTradeNo");
-        }
-
-        Map<String, Object> orderDetail = orderService.getUserOrderDetail(userId, orderId, orderNo, outTradeNo);
+        Map<String, Object> orderDetail = orderService.getUserOrderDetail(userId, params);
         if (orderDetail == null) {
-            return ResponseEnum.ORDER_NOT_FOUND.toResult();
+            return ResponseEnum.PARAM_REQUIRED.toResult("参数错误:必须提供 orderId、orderNo 或 outTradeNo");
         }
-
         log.info("用户 {} 查询订单详情成功", userId);
         return Result.success("查询成功", orderDetail);
     }
@@ -80,16 +54,9 @@ public class OrderController {
     @PostMapping("/cancel")
     public Result<Void> cancelOrder(@RequestBody Map<String, Object> params) {
         Long userId = StpUtil.getLoginIdAsLong();
-
-        if (!params.containsKey("orderId")) {
-            return ResponseEnum.PARAM_REQUIRED.toResult("参数错误:orderId 不能为空");
-        }
-
-        Long orderId = Long.valueOf(params.get("orderId").toString());
-
-        boolean success = orderService.cancelUserOrder(userId, orderId);
+        boolean success = orderService.cancelUserOrder(userId, params);
         if (success) {
-            log.info("用户 {} 取消订单 {} 成功", userId, orderId);
+            log.info("用户 {} 取消订单成功", userId);
             return Result.success("订单已取消", null);
         } else {
             return Result.error("取消订单失败");

+ 23 - 81
haha-miniapp/src/main/java/com/haha/miniapp/controller/PayScoreController.java

@@ -2,21 +2,16 @@ package com.haha.miniapp.controller;
 
 import cn.dev33.satoken.annotation.SaIgnore;
 import cn.dev33.satoken.stp.StpUtil;
-import com.alibaba.fastjson2.JSON;
 import com.haha.common.constant.CallbackConstants;
-import com.haha.common.constant.ResponseEnum;
 import com.haha.common.utils.RequestParseUtil;
 import com.haha.common.vo.Result;
-import com.haha.service.payment.payscore.*;
-import com.haha.service.payment.payscore.PayScoreCreateRequest.PostPayment;
-import com.haha.service.payment.payscore.PayScoreCompleteRequest.PostDiscount;
+import com.haha.service.payment.payscore.PayScoreCallbackResult;
+import com.haha.service.payment.payscore.PayScoreService;
 import jakarta.servlet.http.HttpServletRequest;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.*;
 
-import java.math.BigDecimal;
-import java.util.List;
 import java.util.Map;
 
 /**
@@ -79,19 +74,13 @@ public class PayScoreController {
         log.info("用户 {} 确认开通支付分", userId);
 
         try {
-            if (!params.containsKey("outOrderNo")) {
-                return ResponseEnum.PARAM_REQUIRED.toResult("参数错误:outOrderNo 不能为空");
-            }
-
-            String outOrderNo = params.get("outOrderNo").toString();
-            Map<String, Object> data = payScoreService.confirmEnablePayscore(userId, outOrderNo);
-
+            Map<String, Object> data = payScoreService.confirmUserPayScoreOrder(userId, params);
             if (data != null) {
                 log.info("用户 {} 确认开通支付分成功", userId);
                 return Result.success("开通成功", data);
             } else {
                 log.warn("用户 {} 开通支付分失败", userId);
-                return ResponseEnum.OPERATION_FAILED.toResult("开通失败,请重试");
+                return com.haha.common.constant.ResponseEnum.OPERATION_FAILED.toResult("开通失败,请重试");
             }
         } catch (Exception e) {
             log.error("确认开通支付分失败 - userId: {}", userId, e);
@@ -108,39 +97,19 @@ public class PayScoreController {
             Long userId = StpUtil.getLoginIdAsLong();
             log.info("用户 {} 请求创建支付分服务订单", userId);
 
-            if (!params.containsKey("orderId")) {
-                return ResponseEnum.PARAM_REQUIRED.toResult("参数错误:orderId 不能为空");
-            }
-            if (!params.containsKey("openId")) {
-                return ResponseEnum.PARAM_REQUIRED.toResult("参数错误:openId 不能为空");
-            }
-
-            Long orderId = Long.valueOf(params.get("orderId").toString());
-            String openId = params.get("openId").toString();
-
-            BigDecimal riskFundAmount = null;
-            if (params.containsKey("riskFundAmount")) {
-                riskFundAmount = new BigDecimal(params.get("riskFundAmount").toString());
-            }
-
-            String riskFundName = null;
-            if (params.containsKey("riskFundName")) {
-                riskFundName = params.get("riskFundName").toString();
-            }
-
-            Map<String, Object> data = payScoreService.createUserPayScoreOrder(userId, orderId, openId, riskFundAmount, riskFundName);
+            Map<String, Object> data = payScoreService.createUserPayScoreOrder(userId, params);
             if (data != null) {
-                log.info("创建支付分服务订单成功 - orderId: {}", orderId);
+                log.info("创建支付分服务订单成功 - orderId: {}", params.get("orderId"));
                 return Result.success("创建成功", data);
             } else {
-                return ResponseEnum.OPERATION_FAILED.toResult("创建支付分服务订单失败");
+                return com.haha.common.constant.ResponseEnum.OPERATION_FAILED.toResult("创建支付分服务订单失败");
             }
         } catch (NumberFormatException e) {
             log.error("参数格式错误", e);
-            return ResponseEnum.PARAM_FORMAT_ERROR.toResult();
+            return com.haha.common.constant.ResponseEnum.PARAM_FORMAT_ERROR.toResult();
         } catch (Exception e) {
             log.error("创建支付分服务订单失败", e);
-            return ResponseEnum.OPERATION_FAILED.toResult("创建失败:" + e.getMessage());
+            return com.haha.common.constant.ResponseEnum.OPERATION_FAILED.toResult("创建失败:" + e.getMessage());
         }
     }
 
@@ -153,39 +122,19 @@ public class PayScoreController {
             Long userId = StpUtil.getLoginIdAsLong();
             log.info("用户 {} 请求完结支付分服务订单", userId);
 
-            if (!params.containsKey("orderId")) {
-                return ResponseEnum.PARAM_REQUIRED.toResult("参数错误:orderId 不能为空");
-            }
-            if (!params.containsKey("totalAmount")) {
-                return ResponseEnum.PARAM_REQUIRED.toResult("参数错误:totalAmount 不能为空");
-            }
-
-            Long orderId = Long.valueOf(params.get("orderId").toString());
-            BigDecimal totalAmount = new BigDecimal(params.get("totalAmount").toString());
-
-            List<PostPayment> payments = null;
-            if (params.containsKey("payments")) {
-                payments = JSON.parseArray(params.get("payments").toString(), PostPayment.class);
-            }
-
-            List<PostDiscount> discounts = null;
-            if (params.containsKey("discounts")) {
-                discounts = JSON.parseArray(params.get("discounts").toString(), PostDiscount.class);
-            }
-
-            Map<String, Object> data = payScoreService.completeUserPayScoreOrder(userId, orderId, totalAmount, payments, discounts);
+            Map<String, Object> data = payScoreService.completeUserPayScoreOrder(userId, params);
             if (data != null) {
-                log.info("完结支付分服务订单成功 - orderId: {}", orderId);
+                log.info("完结支付分服务订单成功 - orderId: {}", params.get("orderId"));
                 return Result.success("完结成功", data);
             } else {
-                return ResponseEnum.OPERATION_FAILED.toResult("完结支付分服务订单失败");
+                return com.haha.common.constant.ResponseEnum.OPERATION_FAILED.toResult("完结支付分服务订单失败");
             }
         } catch (NumberFormatException e) {
             log.error("参数格式错误", e);
-            return ResponseEnum.PARAM_FORMAT_ERROR.toResult();
+            return com.haha.common.constant.ResponseEnum.PARAM_FORMAT_ERROR.toResult();
         } catch (Exception e) {
             log.error("完结支付分服务订单失败", e);
-            return ResponseEnum.OPERATION_FAILED.toResult("完结失败:" + e.getMessage());
+            return com.haha.common.constant.ResponseEnum.OPERATION_FAILED.toResult("完结失败:" + e.getMessage());
         }
     }
 
@@ -198,26 +147,19 @@ public class PayScoreController {
             Long userId = StpUtil.getLoginIdAsLong();
             log.info("用户 {} 请求取消支付分服务订单", userId);
 
-            if (!params.containsKey("orderId")) {
-                return ResponseEnum.PARAM_REQUIRED.toResult("参数错误:orderId 不能为空");
-            }
-
-            Long orderId = Long.valueOf(params.get("orderId").toString());
-            String reason = params.containsKey("reason") ? params.get("reason").toString() : "用户取消";
-
-            Map<String, Object> data = payScoreService.cancelUserPayScoreOrder(userId, orderId, reason);
+            Map<String, Object> data = payScoreService.cancelUserPayScoreOrder(userId, params);
             if (data != null) {
-                log.info("取消支付分服务订单成功 - orderId: {}", orderId);
+                log.info("取消支付分服务订单成功 - orderId: {}", params.get("orderId"));
                 return Result.success("取消成功", data);
             } else {
-                return ResponseEnum.OPERATION_FAILED.toResult("取消支付分服务订单失败");
+                return com.haha.common.constant.ResponseEnum.OPERATION_FAILED.toResult("取消支付分服务订单失败");
             }
         } catch (NumberFormatException e) {
             log.error("参数格式错误", e);
-            return ResponseEnum.PARAM_FORMAT_ERROR.toResult();
+            return com.haha.common.constant.ResponseEnum.PARAM_FORMAT_ERROR.toResult();
         } catch (Exception e) {
             log.error("取消支付分服务订单失败", e);
-            return ResponseEnum.OPERATION_FAILED.toResult("取消失败:" + e.getMessage());
+            return com.haha.common.constant.ResponseEnum.OPERATION_FAILED.toResult("取消失败:" + e.getMessage());
         }
     }
 
@@ -235,11 +177,11 @@ public class PayScoreController {
                 log.info("查询支付分服务订单成功 - orderId: {}", orderId);
                 return Result.success("查询成功", data);
             } else {
-                return ResponseEnum.ORDER_NOT_FOUND.toResult("订单不存在或未创建支付分服务订单");
+                return com.haha.common.constant.ResponseEnum.ORDER_NOT_FOUND.toResult("订单不存在或未创建支付分服务订单");
             }
         } catch (Exception e) {
             log.error("查询支付分服务订单失败", e);
-            return ResponseEnum.OPERATION_FAILED.toResult("查询失败:" + e.getMessage());
+            return com.haha.common.constant.ResponseEnum.OPERATION_FAILED.toResult("查询失败:" + e.getMessage());
         }
     }
 
@@ -257,11 +199,11 @@ public class PayScoreController {
                 log.info("同步支付分状态成功 - orderId: {}", orderId);
                 return Result.success("同步成功", null);
             } else {
-                return ResponseEnum.OPERATION_FAILED.toResult("同步失败");
+                return com.haha.common.constant.ResponseEnum.OPERATION_FAILED.toResult("同步失败");
             }
         } catch (Exception e) {
             log.error("同步支付分状态失败", e);
-            return ResponseEnum.OPERATION_FAILED.toResult("同步失败:" + e.getMessage());
+            return com.haha.common.constant.ResponseEnum.OPERATION_FAILED.toResult("同步失败:" + e.getMessage());
         }
     }
 

+ 9 - 69
haha-miniapp/src/main/java/com/haha/miniapp/controller/PaymentController.java

@@ -18,10 +18,8 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.stream.Collectors;
 
 /**
  * 统一支付控制器
@@ -52,43 +50,13 @@ public class PaymentController {
     @PostMapping("/create")
     public Result<PaymentResult> createPayment(@RequestBody Map<String, Object> params) {
         try {
-            // 1. 提取参数
-            if (!params.containsKey("orderId")) {
-                return ResponseEnum.PARAM_REQUIRED.toResult("参数错误:orderId 不能为空");
-            }
-            if (!params.containsKey("channel")) {
-                return ResponseEnum.PARAM_REQUIRED.toResult("参数错误:channel 不能为空");
-            }
-
-            Long orderId = Long.valueOf(params.get("orderId").toString());
-            String channelCode = params.get("channel").toString();
-
-            // 2. 转换 channel 字符串为 PaymentChannel 枚举
-            PaymentChannel channel = PaymentChannel.fromCode(channelCode);
-            if (channel == null) {
-                return ResponseEnum.PARAM_FORMAT_ERROR.toResult("不支持的支付渠道: " + channelCode);
-            }
-
-            // 3. 构建 extra Map
-            Map<String, String> extra = new HashMap<>();
-            if (params.containsKey("openId")) {
-                extra.put("openId", params.get("openId").toString());
-            }
-            if (params.containsKey("buyerId")) {
-                extra.put("buyerId", params.get("buyerId").toString());
-            }
-
-            log.info("创建支付请求 - 订单ID: {}, 渠道: {}", orderId, channel.getDescription());
+            PaymentResult result = paymentService.createPayment(params);
 
-            // 4. 调用 paymentService.createPayment()
-            PaymentResult result = paymentService.createPayment(orderId, channel, extra);
-
-            // 5. 返回结果
             if (result.isSuccess()) {
-                log.info("创建支付成功 - 订单ID: {}, 预支付ID: {}", orderId, result.getPrepayId());
+                log.info("创建支付成功 - 订单ID: {}, 预支付ID: {}", params.get("orderId"), result.getPrepayId());
                 return Result.success("创建支付成功", result);
             } else {
-                log.warn("创建支付失败 - 订单ID: {}, 错误: {}", orderId, result.getErrorMsg());
+                log.warn("创建支付失败 - 订单ID: {}, 错误: {}", params.get("orderId"), result.getErrorMsg());
                 return ResponseEnum.OPERATION_FAILED.toResult(result.getErrorMsg());
             }
 
@@ -129,7 +97,7 @@ public class PaymentController {
                 PayScoreCallbackResult result = payScoreService.handlePayScoreCallback(params);
 
                 if (result.isSuccess()) {
-                    log.info("支付分回调处理成功 - outOrderNo: {}, eventType: {}, state: {}", 
+                    log.info("支付分回调处理成功 - outOrderNo: {}, eventType: {}, state: {}",
                             result.getOutOrderNo(), result.getEventType(), result.getState());
                     return CallbackConstants.WECHAT_PAYSCORE_SUCCESS;
                 } else {
@@ -140,7 +108,7 @@ public class PaymentController {
 
             if ("wechat".equalsIgnoreCase(channel)) {
                 params = RequestParseUtil.parseWechatPayCallbackParams(request);
-                
+
                 String body = (String) params.get("body");
                 if (body != null && !body.isEmpty()) {
                     try {
@@ -190,24 +158,13 @@ public class PaymentController {
     @PostMapping("/refund")
     public Result<RefundResult> refund(@RequestBody Map<String, Object> params) {
         try {
-            // 提取 orderId, reason
-            if (!params.containsKey("orderId")) {
-                return ResponseEnum.PARAM_REQUIRED.toResult("参数错误:orderId 不能为空");
-            }
-
-            Long orderId = Long.valueOf(params.get("orderId").toString());
-            String reason = params.containsKey("reason") ? params.get("reason").toString() : "用户申请退款";
-
-            log.info("退款请求 - 订单ID: {}, 原因: {}", orderId, reason);
-
-            // 调用 paymentService.refund()
-            RefundResult result = paymentService.refund(orderId, reason);
+            RefundResult result = paymentService.refund(params);
 
             if (result.isSuccess()) {
-                log.info("退款成功 - 订单ID: {}, 退款单号: {}", orderId, result.getRefundId());
+                log.info("退款成功 - 订单ID: {}, 退款单号: {}", params.get("orderId"), result.getRefundId());
                 return Result.success("退款成功", result);
             } else {
-                log.warn("退款失败 - 订单ID: {}, 错误: {}", orderId, result.getErrorMsg());
+                log.warn("退款失败 - 订单ID: {}, 错误: {}", params.get("orderId"), result.getErrorMsg());
                 return ResponseEnum.OPERATION_FAILED.toResult(result.getErrorMsg());
             }
 
@@ -229,19 +186,7 @@ public class PaymentController {
     @GetMapping("/channels")
     public Result<List<Map<String, String>>> getChannels() {
         try {
-            // 调用 paymentService.getAvailableChannels()
-            List<PaymentChannel> channels = paymentService.getAvailableChannels();
-
-            // 转换为 [{code: "wechat", name: "微信支付"}, ...] 格式
-            List<Map<String, String>> channelList = channels.stream()
-                    .map(channel -> {
-                        Map<String, String> map = new HashMap<>();
-                        map.put("code", channel.getCode());
-                        map.put("name", channel.getDescription());
-                        return map;
-                    })
-                    .collect(Collectors.toList());
-
+            List<Map<String, String>> channelList = paymentService.getChannelList();
             log.info("获取可用支付渠道 - 数量: {}", channelList.size());
             return Result.success("获取成功", channelList);
 
@@ -263,7 +208,6 @@ public class PaymentController {
         try {
             log.info("查询支付状态 - 订单ID: {}", orderId);
 
-            // 调用 paymentService.queryPaymentStatus()
             PaymentResult result = paymentService.queryPaymentStatus(orderId);
 
             if (result.isSuccess()) {
@@ -287,13 +231,10 @@ public class PaymentController {
      */
     private String buildCallbackSuccessResponse(PaymentChannel channel) {
         if (channel == PaymentChannel.WECHAT) {
-            // 微信支付 V3 返回 JSON 格式
             return CallbackConstants.WECHAT_V3_SUCCESS;
         } else if (channel == PaymentChannel.ALIPAY || channel == PaymentChannel.ALIPAY_CREDIT) {
-            // 支付宝返回 "success" 字符串
             return CallbackConstants.ALIPAY_SUCCESS;
         } else {
-            // 其他渠道默认返回 "success"
             return CallbackConstants.ALIPAY_SUCCESS;
         }
     }
@@ -306,7 +247,6 @@ public class PaymentController {
      */
     private String buildCallbackErrorResponse(String channelCode) {
         if ("wechat".equalsIgnoreCase(channelCode)) {
-            // 微信支付 V3 返回 JSON 格式
             return CallbackConstants.WECHAT_V3_FAIL;
         } else {
             return CallbackConstants.FAIL;

+ 8 - 0
haha-service/src/main/java/com/haha/service/CouponTemplateService.java

@@ -25,6 +25,14 @@ public interface CouponTemplateService extends IService<CouponTemplate> {
 
     List<CouponTemplate> getAvailableTemplates();
 
+    /**
+     * 获取可领取优惠券列表(含用户已领取状态)
+     *
+     * @param userId 用户ID
+     * @return 已填充 alreadyReceived 状态的优惠券模板列表
+     */
+    List<CouponTemplate> getAvailableTemplatesWithStatus(Long userId);
+
     boolean decreaseRemainCount(Long id);
 
     boolean increaseRemainCount(Long id);

+ 9 - 0
haha-service/src/main/java/com/haha/service/DeviceService.java

@@ -130,4 +130,13 @@ public interface DeviceService extends IService<Device> {
      * @return 成功更新的数量
      */
     int batchUpdateDeviceDoorStatus(Map<String, String> deviceStatusMap);
+
+    /**
+     * 根据错误码返回友好的错误信息
+     *
+     * @param errorCode  错误码
+     * @param defaultMsg 默认错误信息
+     * @return 友好的错误描述
+     */
+    String getHahaErrorMessage(Integer errorCode, String defaultMsg);
 }

+ 45 - 0
haha-service/src/main/java/com/haha/service/InviteActivityService.java

@@ -131,6 +131,17 @@ public interface InviteActivityService extends IService<InviteActivity> {
     boolean bindInviteRelation(Long activityId, Long inviterUserId, Long inviteeUserId,
                                String inviteCode, String sourceChannel, String deviceInfo, String ipAddress);
 
+    /**
+     * 绑定邀请关系(自动根据邀请码查询活动ID和邀请人)
+     *
+     * @param inviteeUserId 被邀请人用户ID
+     * @param inviteCode    邀请码
+     * @param sourceChannel 来源渠道
+     * @param deviceInfo    设备信息
+     * @return 是否绑定成功,邀请码无效时返回false
+     */
+    boolean bindInviteRelation(Long inviteeUserId, String inviteCode, String sourceChannel, String deviceInfo);
+
     // ==================== 邀请激活 ====================
 
     /**
@@ -190,6 +201,30 @@ public interface InviteActivityService extends IService<InviteActivity> {
      */
     Map<String, Object> getMyInviteStatistics(Long userId, Long activityId);
 
+    /**
+     * 获取当前用户的邀请统计(自动获取当前活动)
+     *
+     * @param userId 用户ID
+     * @return 用户邀请统计数据,无进行中活动时返回空Map
+     */
+    Map<String, Object> getMyInviteStatistics(Long userId);
+
+    /**
+     * 获取当前用户的邀请码信息(含活动信息和邀请链接)
+     *
+     * @param userId 用户ID
+     * @return 包含 inviteCode、inviteLink、activityInfo 的Map,无活动时返回 null
+     */
+    Map<String, Object> getInviteCodeInfo(Long userId);
+
+    /**
+     * 获取当前用户的邀请海报信息
+     *
+     * @param userId 用户ID
+     * @return 包含 inviteCode、posterUrl 的Map,无活动时返回 null
+     */
+    Map<String, Object> generatePosterInfo(Long userId);
+
     /**
      * 分页查询当前用户的邀请记录列表
      *
@@ -201,6 +236,16 @@ public interface InviteActivityService extends IService<InviteActivity> {
      */
     IPage<InviteRecord> getMyInviteRecords(Long userId, Long activityId, Integer page, Integer pageSize);
 
+    /**
+     * 分页查询当前用户的邀请记录列表(自动获取当前活动)
+     *
+     * @param userId   用户ID
+     * @param page     页码
+     * @param pageSize 每页条数
+     * @return 分页结果,无进行中活动时为空分页
+     */
+    IPage<InviteRecord> getMyInviteRecords(Long userId, Integer page, Integer pageSize);
+
     // ==================== 防刷检查 ====================
 
     /**

+ 9 - 0
haha-service/src/main/java/com/haha/service/LayerTemplateService.java

@@ -97,6 +97,15 @@ public interface LayerTemplateService extends IService<LayerTemplate> {
      */
     Map<String, Object> getProductConfig(String deviceId);
 
+    /**
+     * 获取设备商品陈列信息(小程序首页使用)
+     * 返回左右门层数据和设备基础信息,供小程序展示柜内商品
+     *
+     * @param deviceId 设备ID(SN号)
+     * @return 包含 templateName、deviceId、shelfNum、deviceType、leftFloors、rightFloors 的Map
+     */
+    Map<String, Object> getDeviceProducts(String deviceId);
+
     /**
      * 保存设备商品配置
      *

+ 27 - 0
haha-service/src/main/java/com/haha/service/OrderService.java

@@ -126,6 +126,15 @@ public interface OrderService extends IService<Order> {
      */
     List<Map<String, Object>> getUserOrderListWithProducts(Long userId, Integer status);
 
+    /**
+     * 获取用户订单列表(带商品信息,从params Map提取参数)
+     *
+     * @param userId 用户ID
+     * @param params 包含可选参数 status
+     * @return 订单列表Map
+     */
+    List<Map<String, Object>> getUserOrderListWithProducts(Long userId, Map<String, Object> params);
+
     /**
      * 获取用户订单详情(带商品信息和状态文本)
      *
@@ -137,6 +146,15 @@ public interface OrderService extends IService<Order> {
      */
     Map<String, Object> getUserOrderDetail(Long userId, Long orderId, String orderNo, String outTradeNo);
 
+    /**
+     * 获取用户订单详情(从params Map提取参数)
+     *
+     * @param userId 用户ID
+     * @param params 包含 orderId/orderNo/outTradeNo 中任意一个
+     * @return 订单详情Map,不存在返回null
+     */
+    Map<String, Object> getUserOrderDetail(Long userId, Map<String, Object> params);
+
     /**
      * 取消订单(含权限和状态校验)
      *
@@ -145,4 +163,13 @@ public interface OrderService extends IService<Order> {
      * @return 是否成功
      */
     boolean cancelUserOrder(Long userId, Long orderId);
+
+    /**
+     * 取消订单(从params Map提取orderId)
+     *
+     * @param userId 用户ID
+     * @param params 包含 orderId
+     * @return 是否成功
+     */
+    boolean cancelUserOrder(Long userId, Map<String, Object> params);
 }

+ 13 - 0
haha-service/src/main/java/com/haha/service/impl/CouponTemplateServiceImpl.java

@@ -17,6 +17,7 @@ import com.haha.entity.dto.CouponQueryDTO;
 import com.haha.mapper.CouponProductMapper;
 import com.haha.mapper.CouponShopMapper;
 import com.haha.mapper.CouponTemplateMapper;
+import com.haha.mapper.UserCouponMapper;
 import com.haha.service.CouponTemplateService;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -38,6 +39,7 @@ public class CouponTemplateServiceImpl extends ServiceImpl<CouponTemplateMapper,
     private final CouponTemplateMapper templateMapper;
     private final CouponShopMapper couponShopMapper;
     private final CouponProductMapper couponProductMapper;
+    private final UserCouponMapper userCouponMapper;
 
     @Override
     public IPage<CouponTemplate> getPage(CouponQueryDTO queryDTO) {
@@ -155,6 +157,17 @@ public class CouponTemplateServiceImpl extends ServiceImpl<CouponTemplateMapper,
         return templateMapper.selectAvailableTemplates();
     }
 
+    @Override
+    public List<CouponTemplate> getAvailableTemplatesWithStatus(Long userId) {
+        List<CouponTemplate> templates = templateMapper.selectAvailableTemplates();
+        templates.forEach(template -> {
+            int receivedCount = userCouponMapper.countByTemplateAndUser(template.getId(), userId);
+            template.setAlreadyReceived(receivedCount > 0);
+        });
+        log.info("[优惠券] 可领取优惠券数量: {}", templates.size());
+        return templates;
+    }
+
     @Override
     public boolean decreaseRemainCount(Long id) {
         return templateMapper.decreaseRemainCount(id) > 0;

+ 27 - 0
haha-service/src/main/java/com/haha/service/impl/DeviceServiceImpl.java

@@ -458,4 +458,31 @@ public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> impleme
             return 0;
         }
     }
+
+    @Override
+    public String getHahaErrorMessage(Integer errorCode, String defaultMsg) {
+        if (errorCode == null) {
+            return defaultMsg != null ? defaultMsg : "操作失败";
+        }
+        
+        switch (errorCode) {
+            case -1:
+                return "参数错误,请检查设备ID是否正确";
+            case -2:
+                return "签名错误,请联系技术支持";
+            case -3:
+            case -4:
+                return "认证失败,请稍后重试";
+            case -100:
+                return "设备不存在,请确认设备ID";
+            case -101:
+                return "设备离线,请稍后再试";
+            case -102:
+                return "设备故障,请联系设备维护人员";
+            case -103:
+                return "设备使用中,请稍后再试";
+            default:
+                return defaultMsg != null ? defaultMsg : "开门失败";
+        }
+    }
 }

+ 64 - 0
haha-service/src/main/java/com/haha/service/impl/InviteActivityServiceImpl.java

@@ -498,6 +498,25 @@ public class InviteActivityServiceImpl extends ServiceImpl<InviteActivityMapper,
         return true;
     }
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public boolean bindInviteRelation(Long inviteeUserId, String inviteCode, String sourceChannel, String deviceInfo) {
+        InviteRecord record = getInviteRecordByCode(inviteCode);
+        if (record == null) {
+            log.warn("[邀请] 邀请码无效或已过期 - userId: {}, inviteCode: {}", inviteeUserId, inviteCode);
+            return false;
+        }
+        return bindInviteRelation(
+                record.getActivityId(),
+                record.getInviterUserId(),
+                inviteeUserId,
+                inviteCode,
+                sourceChannel,
+                deviceInfo,
+                ""
+        );
+    }
+
     // ==================== 邀请激活 ====================
 
     @Override
@@ -927,6 +946,42 @@ public class InviteActivityServiceImpl extends ServiceImpl<InviteActivityMapper,
         return stats;
     }
 
+    @Override
+    public Map<String, Object> getMyInviteStatistics(Long userId) {
+        InviteActivity ongoingActivity = getOngoingActivity();
+        if (ongoingActivity == null) {
+            return new HashMap<>();
+        }
+        return getMyInviteStatistics(userId, ongoingActivity.getId());
+    }
+
+    @Override
+    public Map<String, Object> getInviteCodeInfo(Long userId) {
+        InviteActivity ongoingActivity = getOngoingActivity();
+        if (ongoingActivity == null) {
+            return null;
+        }
+        String inviteCode = generateInviteCode(userId, ongoingActivity.getId());
+        Map<String, Object> result = new HashMap<>();
+        result.put("inviteCode", inviteCode);
+        result.put("inviteLink", "pages/index/index?inviteCode=" + inviteCode);
+        result.put("activityInfo", ongoingActivity);
+        return result;
+    }
+
+    @Override
+    public Map<String, Object> generatePosterInfo(Long userId) {
+        InviteActivity ongoingActivity = getOngoingActivity();
+        if (ongoingActivity == null) {
+            return null;
+        }
+        String inviteCode = generateInviteCode(userId, ongoingActivity.getId());
+        Map<String, Object> result = new HashMap<>();
+        result.put("inviteCode", inviteCode);
+        result.put("posterUrl", "");
+        return result;
+    }
+
     @Override
     public IPage<InviteRecord> getMyInviteRecords(Long userId, Long activityId, Integer page, Integer pageSize) {
         // 参数校验
@@ -963,6 +1018,15 @@ public class InviteActivityServiceImpl extends ServiceImpl<InviteActivityMapper,
         return result;
     }
 
+    @Override
+    public IPage<InviteRecord> getMyInviteRecords(Long userId, Integer page, Integer pageSize) {
+        InviteActivity ongoingActivity = getOngoingActivity();
+        if (ongoingActivity == null) {
+            return new Page<>(page, pageSize, 0);
+        }
+        return getMyInviteRecords(userId, ongoingActivity.getId(), page, pageSize);
+    }
+
     @Override
     public IPage<InviteRecord> getInviteRecords(InviteRecordQueryDTO queryDTO) {
         queryDTO.validate();

+ 46 - 0
haha-service/src/main/java/com/haha/service/impl/LayerTemplateServiceImpl.java

@@ -755,6 +755,52 @@ public class LayerTemplateServiceImpl extends ServiceImpl<LayerTemplateMapper, L
         return result;
     }
 
+    @Override
+    public Map<String, Object> getDeviceProducts(String deviceId) {
+        log.info("获取设备商品陈列信息: deviceId={}", deviceId);
+
+        LayerTemplate template = getByDeviceId(deviceId);
+        if (template == null) {
+            return null;
+        }
+
+        Map<String, Object> result = new HashMap<>();
+        result.put("templateName", template.getTemplateName());
+        result.put("deviceId", template.getDeviceId());
+        result.put("shelfNum", template.getShelfNum());
+        result.put("deviceType", template.getDeviceType());
+
+        // 解析左门层数据
+        if (template.getLeftFloors() != null && !template.getLeftFloors().isEmpty()) {
+            try {
+                List<FloorConfig> leftFloors = objectMapper.readValue(
+                    template.getLeftFloors(), new TypeReference<List<FloorConfig>>() {});
+                result.put("leftFloors", leftFloors);
+            } catch (Exception e) {
+                log.warn("解析左门层数据失败, deviceId={}", deviceId, e);
+                result.put("leftFloors", List.of());
+            }
+        } else {
+            result.put("leftFloors", List.of());
+        }
+
+        // 解析右门层数据
+        if (template.getRightFloors() != null && !template.getRightFloors().isEmpty()) {
+            try {
+                List<FloorConfig> rightFloors = objectMapper.readValue(
+                    template.getRightFloors(), new TypeReference<List<FloorConfig>>() {});
+                result.put("rightFloors", rightFloors);
+            } catch (Exception e) {
+                log.warn("解析右门层数据失败, deviceId={}", deviceId, e);
+                result.put("rightFloors", List.of());
+            }
+        } else {
+            result.put("rightFloors", List.of());
+        }
+
+        return result;
+    }
+
     /**
      * 保存设备商品配置
      */

+ 37 - 0
haha-service/src/main/java/com/haha/service/impl/OrderServiceImpl.java

@@ -654,6 +654,15 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
         return orderList;
     }
 
+    @Override
+    public List<Map<String, Object>> getUserOrderListWithProducts(Long userId, Map<String, Object> params) {
+        Integer status = null;
+        if (params != null && params.containsKey("status")) {
+            status = Integer.valueOf(params.get("status").toString());
+        }
+        return getUserOrderListWithProducts(userId, status);
+    }
+
     @Override
     public Map<String, Object> getUserOrderDetail(Long userId, Long orderId, String orderNo, String outTradeNo) {
         Order order = null;
@@ -686,6 +695,25 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
         return detail;
     }
 
+    @Override
+    public Map<String, Object> getUserOrderDetail(Long userId, Map<String, Object> params) {
+        Long orderId = null;
+        String orderNo = null;
+        String outTradeNo = null;
+
+        if (params.containsKey("orderId")) {
+            orderId = Long.valueOf(params.get("orderId").toString());
+        } else if (params.containsKey("orderNo")) {
+            orderNo = params.get("orderNo").toString();
+        } else if (params.containsKey("outTradeNo")) {
+            outTradeNo = params.get("outTradeNo").toString();
+        } else {
+            return null;
+        }
+
+        return getUserOrderDetail(userId, orderId, orderNo, outTradeNo);
+    }
+
     @Override
     public boolean cancelUserOrder(Long userId, Long orderId) {
         Order order = this.getById(orderId);
@@ -701,6 +729,15 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
         return cancelOrder(orderId);
     }
 
+    @Override
+    public boolean cancelUserOrder(Long userId, Map<String, Object> params) {
+        if (params == null || !params.containsKey("orderId")) {
+            return false;
+        }
+        Long orderId = Long.valueOf(params.get("orderId").toString());
+        return cancelUserOrder(userId, orderId);
+    }
+
     /**
      * 构建订单Map(含商品信息)
      */

+ 2 - 4
haha-service/src/main/java/com/haha/service/impl/UserCouponServiceImpl.java

@@ -19,7 +19,6 @@ import com.haha.mapper.CouponDistributeMapper;
 import com.haha.mapper.CouponTemplateMapper;
 import com.haha.mapper.UserCouponMapper;
 import com.haha.mapper.UserMapper;
-import com.haha.service.CouponTemplateService;
 import com.haha.service.UserCouponService;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -44,7 +43,6 @@ public class UserCouponServiceImpl extends ServiceImpl<UserCouponMapper, UserCou
     private final CouponTemplateMapper templateMapper;
     private final CouponDistributeMapper distributeMapper;
     private final UserMapper userMapper;
-    private final CouponTemplateService templateService;
     private final StringRedisTemplate redisTemplate;
 
     @Override
@@ -112,7 +110,7 @@ public class UserCouponServiceImpl extends ServiceImpl<UserCouponMapper, UserCou
                 throw new BusinessException(400, "已达到领取上限");
             }
 
-            if (!templateService.decreaseRemainCount(templateId)) {
+            if (templateMapper.decreaseRemainCount(templateId) <= 0) {
                 log.error("[优惠券服务] 领取优惠券失败 - 扣减库存失败, templateId: {}", templateId);
                 throw new BusinessException(400, "优惠券领取失败,请重试");
             }
@@ -202,7 +200,7 @@ public class UserCouponServiceImpl extends ServiceImpl<UserCouponMapper, UserCou
                 }
 
                 this.save(userCoupon);
-                templateService.decreaseRemainCount(dto.getTemplateId());
+                templateMapper.decreaseRemainCount(dto.getTemplateId());
                 successCount++;
             } catch (Exception e) {
                 log.error("发放优惠券失败: userId={}, templateId={}", userId, dto.getTemplateId(), e);

+ 20 - 0
haha-service/src/main/java/com/haha/service/payment/PaymentService.java

@@ -19,6 +19,13 @@ public interface PaymentService {
      */
     PaymentResult createPayment(Long orderId, PaymentChannel channel, Map<String, String> extra);
     
+    /**
+     * 创建支付(从Map params提取参数)
+     * @param params 包含 orderId、channel、openId(可选)、buyerId(可选)
+     * @return 支付结果
+     */
+    PaymentResult createPayment(Map<String, Object> params);
+
     /**
      * 退款
      * @param orderId 本地订单ID
@@ -26,6 +33,13 @@ public interface PaymentService {
      * @return 退款结果
      */
     RefundResult refund(Long orderId, String reason);
+
+    /**
+     * 退款(从Map params提取orderId和reason)
+     * @param params 包含 orderId、reason(可选)
+     * @return 退款结果
+     */
+    RefundResult refund(Map<String, Object> params);
     
     /**
      * 处理支付回调
@@ -46,4 +60,10 @@ public interface PaymentService {
      * 获取当前可用的支付渠道列表
      */
     List<PaymentChannel> getAvailableChannels();
+
+    /**
+     * 获取可用支付渠道列表(转换为前端所需格式)
+     * @return [{code: "wechat", name: "微信支付"}, ...]
+     */
+    List<Map<String, String>> getChannelList();
 }

+ 78 - 1
haha-service/src/main/java/com/haha/service/payment/impl/PaymentServiceImpl.java

@@ -11,8 +11,10 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.time.LocalDateTime;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * 支付业务门面服务实现
@@ -384,7 +386,82 @@ public class PaymentServiceImpl implements PaymentService {
         log.debug("获取可用支付渠道列表");
         return channelFactory.getAvailableChannels();
     }
-    
+
+    @Override
+    public PaymentResult createPayment(Map<String, Object> params) {
+        // 1. 提取和校验参数
+        if (!params.containsKey("orderId")) {
+            return PaymentResult.builder()
+                    .success(false)
+                    .errorCode("INVALID_PARAM")
+                    .errorMsg("参数错误:orderId 不能为空")
+                    .build();
+        }
+        if (!params.containsKey("channel")) {
+            return PaymentResult.builder()
+                    .success(false)
+                    .errorCode("INVALID_PARAM")
+                    .errorMsg("参数错误:channel 不能为空")
+                    .build();
+        }
+
+        Long orderId = Long.valueOf(params.get("orderId").toString());
+        String channelCode = params.get("channel").toString();
+
+        // 2. 转换 channel 字符串为 PaymentChannel 枚举
+        PaymentChannel channel = PaymentChannel.fromCode(channelCode);
+        if (channel == null) {
+            log.warn("不支持的支付渠道: {}", channelCode);
+            return PaymentResult.builder()
+                    .success(false)
+                    .errorCode("UNSUPPORTED_CHANNEL")
+                    .errorMsg("不支持的支付渠道: " + channelCode)
+                    .build();
+        }
+
+        // 3. 构建 extra Map
+        Map<String, String> extra = new HashMap<>();
+        if (params.containsKey("openId")) {
+            extra.put("openId", params.get("openId").toString());
+        }
+        if (params.containsKey("buyerId")) {
+            extra.put("buyerId", params.get("buyerId").toString());
+        }
+
+        log.info("创建支付请求 - 订单ID: {}, 渠道: {}", orderId, channel.getDescription());
+        return createPayment(orderId, channel, extra);
+    }
+
+    @Override
+    public RefundResult refund(Map<String, Object> params) {
+        if (!params.containsKey("orderId")) {
+            return RefundResult.builder()
+                    .success(false)
+                    .errorCode("INVALID_PARAM")
+                    .errorMsg("参数错误:orderId 不能为空")
+                    .build();
+        }
+
+        Long orderId = Long.valueOf(params.get("orderId").toString());
+        String reason = params.containsKey("reason") ? params.get("reason").toString() : "用户申请退款";
+
+        log.info("退款请求 - 订单ID: {}, 原因: {}", orderId, reason);
+        return refund(orderId, reason);
+    }
+
+    @Override
+    public List<Map<String, String>> getChannelList() {
+        List<PaymentChannel> channels = getAvailableChannels();
+        return channels.stream()
+                .map(channel -> {
+                    Map<String, String> map = new HashMap<>();
+                    map.put("code", channel.getCode());
+                    map.put("name", channel.getDescription());
+                    return map;
+                })
+                .collect(Collectors.toList());
+    }
+
     /**
      * 更新订单退款状态
      */

+ 36 - 0
haha-service/src/main/java/com/haha/service/payment/payscore/PayScoreService.java

@@ -114,6 +114,15 @@ public interface PayScoreService {
      */
     Map<String, Object> confirmEnablePayscore(Long userId, String outOrderNo);
 
+    /**
+     * 确认开通支付分(从Map params提取outOrderNo)
+     *
+     * @param userId 用户ID
+     * @param params 包含 outOrderNo
+     * @return 开通结果Map
+     */
+    Map<String, Object> confirmUserPayScoreOrder(Long userId, Map<String, Object> params);
+
     /**
      * 创建支付分服务订单(含权限校验)
      *
@@ -127,6 +136,15 @@ public interface PayScoreService {
     Map<String, Object> createUserPayScoreOrder(Long userId, Long orderId, String openId,
                                                   BigDecimal riskFundAmount, String riskFundName);
 
+    /**
+     * 创建支付分服务订单(从Map params提取参数)
+     *
+     * @param userId 用户ID
+     * @param params 包含 orderId、openId 等参数
+     * @return 创建结果Map
+     */
+    Map<String, Object> createUserPayScoreOrder(Long userId, Map<String, Object> params);
+
     /**
      * 完结支付分服务订单(含权限校验)
      *
@@ -141,6 +159,15 @@ public interface PayScoreService {
                                                     List<PostPayment> payments,
                                                     List<PayScoreCompleteRequest.PostDiscount> discounts);
 
+    /**
+     * 完结支付分服务订单(从Map params提取参数)
+     *
+     * @param userId 用户ID
+     * @param params 包含 orderId、totalAmount 等参数
+     * @return 完结结果Map
+     */
+    Map<String, Object> completeUserPayScoreOrder(Long userId, Map<String, Object> params);
+
     /**
      * 取消支付分服务订单(含权限校验)
      *
@@ -151,6 +178,15 @@ public interface PayScoreService {
      */
     Map<String, Object> cancelUserPayScoreOrder(Long userId, Long orderId, String reason);
 
+    /**
+     * 取消支付分服务订单(从Map params提取orderId和reason)
+     *
+     * @param userId 用户ID
+     * @param params 包含 orderId、reason(可选)
+     * @return 取消结果Map
+     */
+    Map<String, Object> cancelUserPayScoreOrder(Long userId, Map<String, Object> params);
+
     /**
      * 查询支付分服务订单状态(含权限校验)
      *

+ 76 - 0
haha-service/src/main/java/com/haha/service/payment/payscore/impl/PayScoreServiceImpl.java

@@ -1,5 +1,6 @@
 package com.haha.service.payment.payscore.impl;
 
+import com.alibaba.fastjson2.JSON;
 import com.haha.common.constant.OrderConstants;
 import com.haha.common.enums.OrderStatus;
 import com.haha.common.enums.PayScoreState;
@@ -500,6 +501,81 @@ public class PayScoreServiceImpl implements PayScoreService {
         return syncPayScoreStatus(orderId);
     }
 
+    @Override
+    public Map<String, Object> createUserPayScoreOrder(Long userId, Map<String, Object> params) {
+        if (!params.containsKey("orderId")) {
+            return null;
+        }
+        if (!params.containsKey("openId")) {
+            return null;
+        }
+
+        Long orderId = Long.valueOf(params.get("orderId").toString());
+        String openId = params.get("openId").toString();
+
+        BigDecimal riskFundAmount = null;
+        if (params.containsKey("riskFundAmount")) {
+            riskFundAmount = new BigDecimal(params.get("riskFundAmount").toString());
+        }
+
+        String riskFundName = null;
+        if (params.containsKey("riskFundName")) {
+            riskFundName = params.get("riskFundName").toString();
+        }
+
+        return createUserPayScoreOrder(userId, orderId, openId, riskFundAmount, riskFundName);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Map<String, Object> completeUserPayScoreOrder(Long userId, Map<String, Object> params) {
+        if (!params.containsKey("orderId")) {
+            return null;
+        }
+        if (!params.containsKey("totalAmount")) {
+            return null;
+        }
+
+        Long orderId = Long.valueOf(params.get("orderId").toString());
+        BigDecimal totalAmount = new BigDecimal(params.get("totalAmount").toString());
+
+        List<PostPayment> payments = null;
+        if (params.containsKey("payments")) {
+            payments = JSON.parseArray(params.get("payments").toString(), PostPayment.class);
+        }
+
+        List<PostDiscount> discounts = null;
+        if (params.containsKey("discounts")) {
+            discounts = JSON.parseArray(params.get("discounts").toString(), PostDiscount.class);
+        }
+
+        return completeUserPayScoreOrder(userId, orderId, totalAmount, payments, discounts);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Map<String, Object> confirmUserPayScoreOrder(Long userId, Map<String, Object> params) {
+        if (!params.containsKey("outOrderNo")) {
+            return null;
+        }
+
+        String outOrderNo = params.get("outOrderNo").toString();
+        return confirmEnablePayscore(userId, outOrderNo);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Map<String, Object> cancelUserPayScoreOrder(Long userId, Map<String, Object> params) {
+        if (!params.containsKey("orderId")) {
+            return null;
+        }
+
+        Long orderId = Long.valueOf(params.get("orderId").toString());
+        String reason = params.containsKey("reason") ? params.get("reason").toString() : "用户取消";
+
+        return cancelUserPayScoreOrder(userId, orderId, reason);
+    }
+
     private boolean isPayscoreEnabled(User user) {
         return user != null && user.getPayscoreEnabled() != null && user.getPayscoreEnabled() == PAYSCORE_ENABLED;
     }