feat(pricing): 添加场景优惠券功能

- 创建场景优惠券领取控制器,提供前端优惠券领取接口
- 创建场景优惠券配置管理控制器,提供后台管理端配置接口
- 定义场景优惠券领取和配置相关的请求响应DTO
- 创建场景优惠券配置实体和数据库表结构
- 实现场景优惠券配置的数据访问和业务逻辑处理
- 实现场景优惠券领取功能,支持景区隔离和默认配置回退
- 添加优惠券领取状态检查和用户限制验证逻辑
- 实现分页查询和配置管理功能
This commit is contained in:
2026-01-06 18:30:23 +08:00
parent 123a081eab
commit e0856a1b9c
11 changed files with 1056 additions and 0 deletions

View File

@@ -0,0 +1,92 @@
package com.ycwl.basic.pricing.controller;
import com.ycwl.basic.constant.BaseContextHandler;
import com.ycwl.basic.pricing.dto.CouponClaimResult;
import com.ycwl.basic.pricing.dto.req.SceneCouponClaimReq;
import com.ycwl.basic.pricing.dto.resp.SceneCouponAvailableResp;
import com.ycwl.basic.pricing.service.ISceneCouponService;
import com.ycwl.basic.utils.ApiResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 场景优惠券领取控制器(前端/移动端)
*/
@Slf4j
@RestController
@RequestMapping("/api/pricing/scene-coupon")
@RequiredArgsConstructor
public class SceneCouponClaimController {
private final ISceneCouponService sceneCouponService;
/**
* 查询场景下可领取的优惠券列表
*
* @param sceneKey 场景标识
* @param scenicId 景区ID
* @return 可领取优惠券列表(包含用户领取状态)
*/
@GetMapping("/available")
public ApiResponse<List<SceneCouponAvailableResp>> getAvailableCoupons(
@RequestParam String sceneKey,
@RequestParam Long scenicId) {
try {
Long userId = getUserId();
List<SceneCouponAvailableResp> list = sceneCouponService.getAvailableCoupons(sceneKey, scenicId, userId);
return ApiResponse.success(list);
} catch (Exception e) {
log.error("场景优惠券|可领取列表查询失败 sceneKey={}, scenicId={}", sceneKey, scenicId, e);
return ApiResponse.fail("查询失败: " + e.getMessage());
}
}
/**
* 领取场景优惠券
*
* @param req 领取请求
* @return 领取结果列表
*/
@PostMapping("/claim")
public ApiResponse<List<CouponClaimResult>> claimCoupons(@RequestBody SceneCouponClaimReq req) {
try {
Long userId = getUserId();
if (userId == null) {
return ApiResponse.fail("用户未登录");
}
List<CouponClaimResult> results = sceneCouponService.claimCoupons(req, userId);
// 判断整体结果
boolean hasSuccess = results.stream().anyMatch(CouponClaimResult::isSuccess);
if (!hasSuccess && !results.isEmpty()) {
// 全部失败,返回第一个错误信息
return ApiResponse.fail(results.get(0).getErrorMessage());
}
return ApiResponse.success(results);
} catch (Exception e) {
log.error("场景优惠券|领取失败 req={}", req, e);
return ApiResponse.fail("领取失败: " + e.getMessage());
}
}
/**
* 获取当前登录用户ID
*/
private Long getUserId() {
try {
String userIdStr = BaseContextHandler.getUserId();
if (userIdStr == null || userIdStr.isEmpty()) {
return null;
}
return Long.valueOf(userIdStr);
} catch (NumberFormatException e) {
log.warn("无法解析用户ID: {}", BaseContextHandler.getUserId());
return null;
}
}
}