You've already forked FrameTour-BE
feat(pricing): 增加景区优惠券统计功能并优化优惠券使用逻辑
- 新增景区优惠券统计接口和相关查询方法 - 为优惠券配置和使用记录添加景区ID字段 - 实现优惠券使用时的景区限制检查 - 优化优惠券适用性的判断逻辑,增加对景区和商品类型的检查
This commit is contained in:
@@ -40,18 +40,19 @@ public interface PriceCouponClaimRecordMapper extends BaseMapper<PriceCouponClai
|
||||
* 更新优惠券使用状态
|
||||
*/
|
||||
@Update("UPDATE price_coupon_claim_record SET status = #{status}, " +
|
||||
"use_time = #{useTime}, order_id = #{orderId}, updated_time = NOW() " +
|
||||
"use_time = #{useTime}, order_id = #{orderId}, scenic_id = #{scenicId}, updated_time = NOW() " +
|
||||
"WHERE id = #{id}")
|
||||
int updateCouponStatus(@Param("id") Long id,
|
||||
@Param("status") CouponStatus status,
|
||||
@Param("useTime") java.time.LocalDateTime useTime,
|
||||
@Param("orderId") String orderId);
|
||||
@Param("orderId") String orderId,
|
||||
@Param("scenicId") String scenicId);
|
||||
|
||||
/**
|
||||
* 插入优惠券领用记录
|
||||
*/
|
||||
@Insert("INSERT INTO price_coupon_claim_record (coupon_id, user_id, claim_time, status, created_time, updated_time) " +
|
||||
"VALUES (#{couponId}, #{userId}, NOW(), #{status}, NOW(), NOW())")
|
||||
@Insert("INSERT INTO price_coupon_claim_record (coupon_id, user_id, claim_time, status, scenic_id, created_time, updated_time) " +
|
||||
"VALUES (#{couponId}, #{userId}, NOW(), #{status}, #{scenicId}, NOW(), NOW())")
|
||||
int insertClaimRecord(PriceCouponClaimRecord record);
|
||||
|
||||
/**
|
||||
@@ -95,6 +96,9 @@ public interface PriceCouponClaimRecordMapper extends BaseMapper<PriceCouponClai
|
||||
"<if test='endTime != null and endTime != \"\"'>" +
|
||||
"AND r.claim_time <= #{endTime}" +
|
||||
"</if>" +
|
||||
"<if test='scenicId != null and scenicId != \"\"'>" +
|
||||
"AND r.scenic_id = #{scenicId}" +
|
||||
"</if>" +
|
||||
"</where>" +
|
||||
"ORDER BY r.created_time DESC" +
|
||||
"</script>")
|
||||
@@ -102,7 +106,8 @@ public interface PriceCouponClaimRecordMapper extends BaseMapper<PriceCouponClai
|
||||
@Param("couponId") Long couponId,
|
||||
@Param("status") CouponStatus status,
|
||||
@Param("startTime") String startTime,
|
||||
@Param("endTime") String endTime);
|
||||
@Param("endTime") String endTime,
|
||||
@Param("scenicId") String scenicId);
|
||||
|
||||
/**
|
||||
* 管理端:根据用户ID查询优惠券领取记录
|
||||
@@ -161,7 +166,8 @@ public interface PriceCouponClaimRecordMapper extends BaseMapper<PriceCouponClai
|
||||
/**
|
||||
* 管理端:统计时间范围内的数据
|
||||
*/
|
||||
@Select("SELECT " +
|
||||
@Select("<script>" +
|
||||
"SELECT " +
|
||||
"COUNT(*) as total_claimed, " +
|
||||
"COUNT(CASE WHEN status = 'USED' THEN 1 END) as total_used, " +
|
||||
"COUNT(CASE WHEN status = 'CLAIMED' THEN 1 END) as total_available, " +
|
||||
@@ -169,7 +175,35 @@ public interface PriceCouponClaimRecordMapper extends BaseMapper<PriceCouponClai
|
||||
"COUNT(DISTINCT coupon_id) as total_coupon_types, " +
|
||||
"COUNT(DISTINCT user_id) as total_users " +
|
||||
"FROM price_coupon_claim_record " +
|
||||
"WHERE claim_time >= #{startDate} AND claim_time <= #{endDate}")
|
||||
"WHERE claim_time >= #{startDate} AND claim_time <= #{endDate} " +
|
||||
"<if test='scenicId != null and scenicId != \"\"'>" +
|
||||
"AND scenic_id = #{scenicId} " +
|
||||
"</if>" +
|
||||
"</script>")
|
||||
java.util.Map<String, Object> selectPeriodStats(@Param("startDate") String startDate,
|
||||
@Param("endDate") String endDate);
|
||||
@Param("endDate") String endDate,
|
||||
@Param("scenicId") String scenicId);
|
||||
|
||||
/**
|
||||
* 根据景区ID查询优惠券领取记录
|
||||
*/
|
||||
@Select("SELECT r.*, c.coupon_name, c.coupon_type, c.discount_value " +
|
||||
"FROM price_coupon_claim_record r " +
|
||||
"LEFT JOIN price_coupon_config c ON r.coupon_id = c.id " +
|
||||
"WHERE r.scenic_id = #{scenicId} " +
|
||||
"ORDER BY r.created_time DESC")
|
||||
List<PriceCouponClaimRecord> selectByScenicIdForAdmin(@Param("scenicId") String scenicId);
|
||||
|
||||
/**
|
||||
* 统计景区优惠券使用情况
|
||||
*/
|
||||
@Select("SELECT " +
|
||||
"COUNT(*) as total_claimed, " +
|
||||
"COUNT(CASE WHEN status = 'USED' THEN 1 END) as total_used, " +
|
||||
"COUNT(CASE WHEN status = 'CLAIMED' THEN 1 END) as total_available, " +
|
||||
"COUNT(CASE WHEN status = 'EXPIRED' THEN 1 END) as total_expired, " +
|
||||
"COUNT(DISTINCT coupon_id) as total_coupon_types, " +
|
||||
"COUNT(DISTINCT user_id) as total_users " +
|
||||
"FROM price_coupon_claim_record WHERE scenic_id = #{scenicId}")
|
||||
java.util.Map<String, Object> selectScenicCouponUsageStats(@Param("scenicId") String scenicId);
|
||||
}
|
||||
@@ -44,10 +44,10 @@ public interface PriceCouponConfigMapper extends BaseMapper<PriceCouponConfig> {
|
||||
*/
|
||||
@Insert("INSERT INTO price_coupon_config (coupon_name, coupon_type, discount_value, min_amount, " +
|
||||
"max_discount, applicable_products, total_quantity, used_quantity, valid_from, valid_until, " +
|
||||
"is_active, created_time, updated_time) VALUES " +
|
||||
"is_active, scenic_id, created_time, updated_time) VALUES " +
|
||||
"(#{couponName}, #{couponType}, #{discountValue}, #{minAmount}, #{maxDiscount}, " +
|
||||
"#{applicableProducts}, #{totalQuantity}, #{usedQuantity}, #{validFrom}, #{validUntil}, " +
|
||||
"#{isActive}, NOW(), NOW())")
|
||||
"#{isActive}, #{scenicId}, NOW(), NOW())")
|
||||
int insertCoupon(PriceCouponConfig coupon);
|
||||
|
||||
/**
|
||||
@@ -57,7 +57,7 @@ public interface PriceCouponConfigMapper extends BaseMapper<PriceCouponConfig> {
|
||||
"discount_value = #{discountValue}, min_amount = #{minAmount}, max_discount = #{maxDiscount}, " +
|
||||
"applicable_products = #{applicableProducts}, total_quantity = #{totalQuantity}, " +
|
||||
"valid_from = #{validFrom}, valid_until = #{validUntil}, is_active = #{isActive}, " +
|
||||
"updated_time = NOW() WHERE id = #{id}")
|
||||
"scenic_id = #{scenicId}, updated_time = NOW() WHERE id = #{id}")
|
||||
int updateCoupon(PriceCouponConfig coupon);
|
||||
|
||||
// ==================== 管理端接口 ====================
|
||||
@@ -80,11 +80,15 @@ public interface PriceCouponConfigMapper extends BaseMapper<PriceCouponConfig> {
|
||||
"<if test='couponName != null and couponName != \"\"'>" +
|
||||
"AND coupon_name LIKE CONCAT('%', #{couponName}, '%')" +
|
||||
"</if>" +
|
||||
"<if test='scenicId != null and scenicId != \"\"'>" +
|
||||
"AND scenic_id = #{scenicId}" +
|
||||
"</if>" +
|
||||
"</where>" +
|
||||
"ORDER BY created_time DESC" +
|
||||
"</script>")
|
||||
List<PriceCouponConfig> selectByConditionsForAdmin(@Param("isActive") Boolean isActive,
|
||||
@Param("couponName") String couponName);
|
||||
@Param("couponName") String couponName,
|
||||
@Param("scenicId") String scenicId);
|
||||
|
||||
/**
|
||||
* 管理端:根据状态查询优惠券配置
|
||||
@@ -103,4 +107,30 @@ public interface PriceCouponConfigMapper extends BaseMapper<PriceCouponConfig> {
|
||||
*/
|
||||
@Update("UPDATE price_coupon_config SET deleted = 1, updated_time = NOW() WHERE id = #{id}")
|
||||
int deleteCoupon(Long id);
|
||||
|
||||
/**
|
||||
* 查询指定景区的有效优惠券配置
|
||||
*/
|
||||
@Select("SELECT * FROM price_coupon_config WHERE is_active = 1 " +
|
||||
"AND valid_from <= NOW() AND valid_until > NOW() " +
|
||||
"AND used_quantity < total_quantity " +
|
||||
"AND (scenic_id IS NULL OR scenic_id = #{scenicId})")
|
||||
List<PriceCouponConfig> selectValidCouponsByScenicId(@Param("scenicId") String scenicId);
|
||||
|
||||
/**
|
||||
* 管理端:根据景区ID查询优惠券配置
|
||||
*/
|
||||
@Select("SELECT * FROM price_coupon_config WHERE scenic_id = #{scenicId} ORDER BY created_time DESC")
|
||||
List<PriceCouponConfig> selectByScenicIdForAdmin(@Param("scenicId") String scenicId);
|
||||
|
||||
/**
|
||||
* 统计景区优惠券配置数量
|
||||
*/
|
||||
@Select("SELECT " +
|
||||
"COUNT(*) as total_coupons, " +
|
||||
"COUNT(CASE WHEN is_active = 1 THEN 1 END) as active_coupons, " +
|
||||
"SUM(total_quantity) as total_quantity, " +
|
||||
"SUM(used_quantity) as used_quantity " +
|
||||
"FROM price_coupon_config WHERE scenic_id = #{scenicId}")
|
||||
java.util.Map<String, Object> selectScenicCouponConfigStats(@Param("scenicId") String scenicId);
|
||||
}
|
||||
Reference in New Issue
Block a user