diff --git a/src/main/java/com/ycwl/basic/pricing/controller/CouponManagementController.java b/src/main/java/com/ycwl/basic/pricing/controller/CouponManagementController.java new file mode 100644 index 0000000..46d66ca --- /dev/null +++ b/src/main/java/com/ycwl/basic/pricing/controller/CouponManagementController.java @@ -0,0 +1,220 @@ +package com.ycwl.basic.pricing.controller; + +import com.github.pagehelper.PageInfo; +import com.ycwl.basic.pricing.entity.PriceCouponClaimRecord; +import com.ycwl.basic.pricing.entity.PriceCouponConfig; +import com.ycwl.basic.pricing.enums.CouponStatus; +import com.ycwl.basic.pricing.service.ICouponManagementService; +import com.ycwl.basic.utils.ApiResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Map; + +/** + * 优惠券管理控制器(管理端) + */ +@Slf4j +@RestController +@RequestMapping("/api/pricing/admin/coupons") +@RequiredArgsConstructor +public class CouponManagementController { + + private final ICouponManagementService couponManagementService; + + // ==================== 优惠券配置管理 ==================== + + /** + * 创建优惠券配置 + */ + @PostMapping("/configs") + public ApiResponse createCouponConfig(@RequestBody PriceCouponConfig config) { + log.info("创建优惠券配置: {}", config.getCouponName()); + Long id = couponManagementService.createCouponConfig(config); + return ApiResponse.success(id); + } + + /** + * 更新优惠券配置 + */ + @PutMapping("/configs/{id}") + public ApiResponse updateCouponConfig(@PathVariable Long id, @RequestBody PriceCouponConfig config) { + log.info("更新优惠券配置: id={}, name={}", id, config.getCouponName()); + config.setId(id); + boolean success = couponManagementService.updateCouponConfig(config); + return ApiResponse.success(success); + } + + /** + * 删除优惠券配置 + */ + @DeleteMapping("/configs/{id}") + public ApiResponse deleteCouponConfig(@PathVariable Long id) { + log.info("删除优惠券配置: id={}", id); + boolean success = couponManagementService.deleteCouponConfig(id); + return ApiResponse.success(success); + } + + /** + * 启用/禁用优惠券配置 + */ + @PutMapping("/configs/{id}/status") + public ApiResponse updateCouponConfigStatus(@PathVariable Long id, @RequestParam Boolean isActive) { + log.info("修改优惠券配置状态: id={}, isActive={}", id, isActive); + boolean success = couponManagementService.updateCouponConfigStatus(id, isActive); + return ApiResponse.success(success); + } + + /** + * 查询所有优惠券配置(包含禁用的) + */ + @GetMapping("/configs") + public ApiResponse> getAllCouponConfigs() { + log.info("管理端获取所有优惠券配置"); + List configs = couponManagementService.getAllCouponConfigs(); + return ApiResponse.success(configs); + } + + /** + * 分页查询优惠券配置 + */ + @GetMapping("/configs/page") + public ApiResponse> getCouponConfigsPage( + @RequestParam(defaultValue = "1") Integer pageNum, + @RequestParam(defaultValue = "10") Integer pageSize, + @RequestParam(required = false) Boolean isActive, + @RequestParam(required = false) String couponName) { + log.info("分页查询优惠券配置: pageNum={}, pageSize={}, isActive={}, couponName={}", + pageNum, pageSize, isActive, couponName); + PageInfo pageInfo = couponManagementService.getCouponConfigsPage( + pageNum, pageSize, isActive, couponName); + return ApiResponse.success(pageInfo); + } + + /** + * 根据状态查询优惠券配置 + */ + @GetMapping("/configs/status/{isActive}") + public ApiResponse> getCouponConfigsByStatus(@PathVariable Boolean isActive) { + log.info("根据状态查询优惠券配置: {}", isActive); + List configs = couponManagementService.getCouponConfigsByStatus(isActive); + return ApiResponse.success(configs); + } + + /** + * 根据ID查询优惠券配置 + */ + @GetMapping("/configs/{id}") + public ApiResponse getCouponConfigById(@PathVariable Long id) { + log.info("根据ID查询优惠券配置: {}", id); + PriceCouponConfig config = couponManagementService.getCouponConfigById(id); + return ApiResponse.success(config); + } + + // ==================== 优惠券领取记录查询 ==================== + + /** + * 查询所有优惠券领取记录 + */ + @GetMapping("/claim-records") + public ApiResponse> getAllClaimRecords() { + log.info("查询所有优惠券领取记录"); + List records = couponManagementService.getAllClaimRecords(); + return ApiResponse.success(records); + } + + /** + * 分页查询优惠券领取记录 + */ + @GetMapping("/claim-records/page") + public ApiResponse> getClaimRecordsPage( + @RequestParam(defaultValue = "1") Integer pageNum, + @RequestParam(defaultValue = "10") Integer pageSize, + @RequestParam(required = false) Long userId, + @RequestParam(required = false) Long couponId, + @RequestParam(required = false) CouponStatus status, + @RequestParam(required = false) String startTime, + @RequestParam(required = false) String endTime) { + log.info("分页查询优惠券领取记录: pageNum={}, pageSize={}, userId={}, couponId={}, status={}, startTime={}, endTime={}", + pageNum, pageSize, userId, couponId, status, startTime, endTime); + PageInfo pageInfo = couponManagementService.getClaimRecordsPage( + pageNum, pageSize, userId, couponId, status, startTime, endTime); + return ApiResponse.success(pageInfo); + } + + /** + * 根据用户ID查询优惠券领取记录 + */ + @GetMapping("/claim-records/user/{userId}") + public ApiResponse> getClaimRecordsByUserId(@PathVariable Long userId) { + log.info("根据用户ID查询优惠券领取记录: {}", userId); + List records = couponManagementService.getClaimRecordsByUserId(userId); + return ApiResponse.success(records); + } + + /** + * 根据优惠券ID查询领取记录 + */ + @GetMapping("/claim-records/coupon/{couponId}") + public ApiResponse> getClaimRecordsByCouponId(@PathVariable Long couponId) { + log.info("根据优惠券ID查询领取记录: {}", couponId); + List records = couponManagementService.getClaimRecordsByCouponId(couponId); + return ApiResponse.success(records); + } + + /** + * 根据状态查询领取记录 + */ + @GetMapping("/claim-records/status/{status}") + public ApiResponse> getClaimRecordsByStatus(@PathVariable CouponStatus status) { + log.info("根据状态查询领取记录: {}", status); + List records = couponManagementService.getClaimRecordsByStatus(status); + return ApiResponse.success(records); + } + + // ==================== 统计功能 ==================== + + /** + * 查询优惠券使用统计 + */ + @GetMapping("/stats/{couponId}") + public ApiResponse> getCouponUsageStats(@PathVariable Long couponId) { + log.info("查询优惠券使用统计: {}", couponId); + Map stats = couponManagementService.getCouponUsageStats(couponId); + return ApiResponse.success(stats); + } + + /** + * 查询优惠券详细统计 + */ + @GetMapping("/stats/{couponId}/detail") + public ApiResponse> getCouponDetailStats(@PathVariable Long couponId) { + log.info("查询优惠券详细统计: {}", couponId); + Map stats = couponManagementService.getCouponDetailStats(couponId); + return ApiResponse.success(stats); + } + + /** + * 查询时间范围内的统计数据 + */ + @GetMapping("/stats/period") + public ApiResponse> getPeriodStats( + @RequestParam String startDate, + @RequestParam String endDate) { + log.info("查询时间范围统计: startDate={}, endDate={}", startDate, endDate); + Map stats = couponManagementService.getPeriodStats(startDate, endDate); + return ApiResponse.success(stats); + } + + /** + * 查询所有优惠券的使用统计概览 + */ + @GetMapping("/stats/overview") + public ApiResponse>> getAllCouponUsageOverview() { + log.info("查询所有优惠券使用统计概览"); + List> overview = couponManagementService.getAllCouponUsageOverview(); + return ApiResponse.success(overview); + } +} \ No newline at end of file diff --git a/src/main/java/com/ycwl/basic/pricing/controller/PricingConfigController.java b/src/main/java/com/ycwl/basic/pricing/controller/PricingConfigController.java index 74125f0..63002a1 100644 --- a/src/main/java/com/ycwl/basic/pricing/controller/PricingConfigController.java +++ b/src/main/java/com/ycwl/basic/pricing/controller/PricingConfigController.java @@ -4,9 +4,12 @@ import com.ycwl.basic.utils.ApiResponse; import com.ycwl.basic.pricing.entity.PriceProductConfig; import com.ycwl.basic.pricing.entity.PriceTierConfig; import com.ycwl.basic.pricing.entity.PriceBundleConfig; +import com.ycwl.basic.pricing.entity.PriceCouponConfig; +import com.ycwl.basic.pricing.entity.PriceCouponClaimRecord; import com.ycwl.basic.pricing.service.IProductConfigService; import com.ycwl.basic.pricing.service.IPriceBundleService; import com.ycwl.basic.pricing.service.IPricingManagementService; +import com.ycwl.basic.pricing.service.ICouponManagementService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; @@ -25,6 +28,7 @@ public class PricingConfigController { private final IProductConfigService productConfigService; private final IPriceBundleService bundleService; private final IPricingManagementService managementService; + private final ICouponManagementService couponManagementService; // ==================== 查询API ==================== @@ -273,4 +277,24 @@ public class PricingConfigController { List configs = bundleService.getAllBundlesForAdmin(); return ApiResponse.success(configs); } + + /** + * 管理端:获取所有优惠券配置(包含禁用的) + */ + @GetMapping("/admin/coupons") + public ApiResponse> getAllCouponConfigsForAdmin() { + log.info("管理端获取所有优惠券配置"); + List configs = couponManagementService.getAllCouponConfigs(); + return ApiResponse.success(configs); + } + + /** + * 管理端:获取所有优惠券领取记录 + */ + @GetMapping("/admin/coupon-records") + public ApiResponse> getAllCouponClaimRecordsForAdmin() { + log.info("管理端获取所有优惠券领取记录"); + List records = couponManagementService.getAllClaimRecords(); + return ApiResponse.success(records); + } } \ No newline at end of file diff --git a/src/main/java/com/ycwl/basic/pricing/handler/BundleProductListTypeHandler.java b/src/main/java/com/ycwl/basic/pricing/handler/BundleProductListTypeHandler.java new file mode 100644 index 0000000..d6d9c8b --- /dev/null +++ b/src/main/java/com/ycwl/basic/pricing/handler/BundleProductListTypeHandler.java @@ -0,0 +1,72 @@ +package com.ycwl.basic.pricing.handler; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.ycwl.basic.pricing.dto.BundleProductItem; +import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.type.BaseTypeHandler; +import org.apache.ibatis.type.JdbcType; + +import java.sql.CallableStatement; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +/** + * 一口价商品列表类型处理器 + */ +@Slf4j +public class BundleProductListTypeHandler extends BaseTypeHandler> { + + private final ObjectMapper objectMapper = new ObjectMapper(); + private final TypeReference> typeReference = new TypeReference>() {}; + + @Override + public void setNonNullParameter(PreparedStatement ps, int i, List parameter, JdbcType jdbcType) throws SQLException { + try { + String json = objectMapper.writeValueAsString(parameter); + ps.setString(i, json); + log.debug("序列化商品列表: {}", json); + } catch (JsonProcessingException e) { + log.error("序列化商品列表失败", e); + throw new SQLException("序列化商品列表失败", e); + } + } + + @Override + public List getNullableResult(ResultSet rs, String columnName) throws SQLException { + String json = rs.getString(columnName); + return parseJson(json, columnName); + } + + @Override + public List getNullableResult(ResultSet rs, int columnIndex) throws SQLException { + String json = rs.getString(columnIndex); + return parseJson(json, "columnIndex:" + columnIndex); + } + + @Override + public List getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { + String json = cs.getString(columnIndex); + return parseJson(json, "columnIndex:" + columnIndex); + } + + private List parseJson(String json, String source) { + if (json == null || json.trim().isEmpty()) { + log.debug("从{}获取的JSON为空,返回空列表", source); + return new ArrayList<>(); + } + + try { + List result = objectMapper.readValue(json, typeReference); + log.debug("从{}反序列化商品列表成功,数量: {}", source, result != null ? result.size() : 0); + return result != null ? result : new ArrayList<>(); + } catch (JsonProcessingException e) { + log.error("从{}反序列化商品列表失败,JSON: {}", source, json, e); + return new ArrayList<>(); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/ycwl/basic/pricing/mapper/PriceCouponClaimRecordMapper.java b/src/main/java/com/ycwl/basic/pricing/mapper/PriceCouponClaimRecordMapper.java index 87ef06d..9c0dfd4 100644 --- a/src/main/java/com/ycwl/basic/pricing/mapper/PriceCouponClaimRecordMapper.java +++ b/src/main/java/com/ycwl/basic/pricing/mapper/PriceCouponClaimRecordMapper.java @@ -60,4 +60,116 @@ public interface PriceCouponClaimRecordMapper extends BaseMapper selectAllForAdmin(); + + /** + * 管理端:根据条件查询优惠券领取记录(支持分页) + */ + @Select("") + List selectByConditionsForAdmin(@Param("userId") Long userId, + @Param("couponId") Long couponId, + @Param("status") CouponStatus status, + @Param("startTime") String startTime, + @Param("endTime") String endTime); + + /** + * 管理端:根据用户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.user_id = #{userId} " + + "ORDER BY r.created_time DESC") + List selectByUserIdForAdmin(@Param("userId") Long userId); + + /** + * 管理端:根据优惠券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.coupon_id = #{couponId} " + + "ORDER BY r.created_time DESC") + List selectByCouponIdForAdmin(@Param("couponId") Long couponId); + + /** + * 管理端:根据状态查询领取记录 + */ + @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.status = #{status} " + + "ORDER BY r.created_time DESC") + List selectByStatusForAdmin(@Param("status") CouponStatus status); + + /** + * 管理端:统计优惠券使用情况 + */ + @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 " + + "FROM price_coupon_claim_record WHERE coupon_id = #{couponId}") + java.util.Map selectCouponUsageStats(@Param("couponId") Long couponId); + + /** + * 管理端:统计优惠券详细使用情况 + */ + @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, " + + "CASE WHEN COUNT(*) > 0 THEN COUNT(CASE WHEN status = 'USED' THEN 1 END) / COUNT(*) ELSE 0 END as usage_rate, " + + "CASE WHEN COUNT(CASE WHEN status = 'USED' THEN 1 END) > 0 THEN " + + "AVG(CASE WHEN status = 'USED' AND use_time IS NOT NULL AND claim_time IS NOT NULL THEN " + + "DATEDIFF(use_time, claim_time) END) ELSE 0 END as avg_days_to_use " + + "FROM price_coupon_claim_record WHERE coupon_id = #{couponId}") + java.util.Map selectCouponDetailStats(@Param("couponId") Long couponId); + + /** + * 管理端:统计时间范围内的数据 + */ + @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 claim_time >= #{startDate} AND claim_time <= #{endDate}") + java.util.Map selectPeriodStats(@Param("startDate") String startDate, + @Param("endDate") String endDate); } \ No newline at end of file diff --git a/src/main/java/com/ycwl/basic/pricing/mapper/PriceCouponConfigMapper.java b/src/main/java/com/ycwl/basic/pricing/mapper/PriceCouponConfigMapper.java index 869a4b6..c44585d 100644 --- a/src/main/java/com/ycwl/basic/pricing/mapper/PriceCouponConfigMapper.java +++ b/src/main/java/com/ycwl/basic/pricing/mapper/PriceCouponConfigMapper.java @@ -59,4 +59,48 @@ public interface PriceCouponConfigMapper extends BaseMapper { "valid_from = #{validFrom}, valid_until = #{validUntil}, is_active = #{isActive}, " + "updated_time = NOW() WHERE id = #{id}") int updateCoupon(PriceCouponConfig coupon); + + // ==================== 管理端接口 ==================== + + /** + * 管理端:查询所有优惠券配置(包含禁用的) + */ + @Select("SELECT * FROM price_coupon_config ORDER BY created_time DESC") + List selectAllForAdmin(); + + /** + * 管理端:根据条件查询优惠券配置(支持分页) + */ + @Select("") + List selectByConditionsForAdmin(@Param("isActive") Boolean isActive, + @Param("couponName") String couponName); + + /** + * 管理端:根据状态查询优惠券配置 + */ + @Select("SELECT * FROM price_coupon_config WHERE is_active = #{isActive} ORDER BY created_time DESC") + List selectByStatusForAdmin(@Param("isActive") Boolean isActive); + + /** + * 管理端:更新优惠券状态 + */ + @Update("UPDATE price_coupon_config SET is_active = #{isActive}, updated_time = NOW() WHERE id = #{id}") + int updateCouponStatus(@Param("id") Long id, @Param("isActive") Boolean isActive); + + /** + * 管理端:删除优惠券配置 + */ + @Update("UPDATE price_coupon_config SET deleted = 1, updated_time = NOW() WHERE id = #{id}") + int deleteCoupon(Long id); } \ No newline at end of file diff --git a/src/main/java/com/ycwl/basic/pricing/service/ICouponManagementService.java b/src/main/java/com/ycwl/basic/pricing/service/ICouponManagementService.java new file mode 100644 index 0000000..61b6583 --- /dev/null +++ b/src/main/java/com/ycwl/basic/pricing/service/ICouponManagementService.java @@ -0,0 +1,107 @@ +package com.ycwl.basic.pricing.service; + +import com.github.pagehelper.PageInfo; +import com.ycwl.basic.pricing.entity.PriceCouponClaimRecord; +import com.ycwl.basic.pricing.entity.PriceCouponConfig; +import com.ycwl.basic.pricing.enums.CouponStatus; + +import java.util.List; +import java.util.Map; + +/** + * 优惠券管理服务接口(管理端) + */ +public interface ICouponManagementService { + + // ==================== 优惠券配置管理 ==================== + + /** + * 创建优惠券配置 + */ + Long createCouponConfig(PriceCouponConfig config); + + /** + * 更新优惠券配置 + */ + boolean updateCouponConfig(PriceCouponConfig config); + + /** + * 删除优惠券配置 + */ + boolean deleteCouponConfig(Long id); + + /** + * 启用/禁用优惠券配置 + */ + boolean updateCouponConfigStatus(Long id, Boolean isActive); + + /** + * 查询所有优惠券配置(包含禁用的) + */ + List getAllCouponConfigs(); + + /** + * 分页查询优惠券配置 + */ + PageInfo getCouponConfigsPage(Integer pageNum, Integer pageSize, + Boolean isActive, String couponName); + + /** + * 根据状态查询优惠券配置 + */ + List getCouponConfigsByStatus(Boolean isActive); + + /** + * 根据ID查询优惠券配置 + */ + PriceCouponConfig getCouponConfigById(Long id); + + // ==================== 优惠券领取记录查询 ==================== + + /** + * 查询所有优惠券领取记录 + */ + List getAllClaimRecords(); + + /** + * 分页查询优惠券领取记录 + */ + PageInfo getClaimRecordsPage(Integer pageNum, Integer pageSize, + Long userId, Long couponId, CouponStatus status, + String startTime, String endTime); + + /** + * 根据用户ID查询优惠券领取记录 + */ + List getClaimRecordsByUserId(Long userId); + + /** + * 根据优惠券ID查询领取记录 + */ + List getClaimRecordsByCouponId(Long couponId); + + /** + * 根据状态查询领取记录 + */ + List getClaimRecordsByStatus(CouponStatus status); + + /** + * 查询优惠券使用统计 + */ + Map getCouponUsageStats(Long couponId); + + /** + * 查询优惠券配置详细统计 + */ + Map getCouponDetailStats(Long couponId); + + /** + * 查询时间范围内的统计数据 + */ + Map getPeriodStats(String startDate, String endDate); + + /** + * 查询所有优惠券的使用统计概览 + */ + List> getAllCouponUsageOverview(); +} \ No newline at end of file diff --git a/src/main/java/com/ycwl/basic/pricing/service/impl/CouponManagementServiceImpl.java b/src/main/java/com/ycwl/basic/pricing/service/impl/CouponManagementServiceImpl.java new file mode 100644 index 0000000..c7ccd42 --- /dev/null +++ b/src/main/java/com/ycwl/basic/pricing/service/impl/CouponManagementServiceImpl.java @@ -0,0 +1,234 @@ +package com.ycwl.basic.pricing.service.impl; + +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; +import com.ycwl.basic.pricing.entity.PriceCouponClaimRecord; +import com.ycwl.basic.pricing.entity.PriceCouponConfig; +import com.ycwl.basic.pricing.enums.CouponStatus; +import com.ycwl.basic.pricing.mapper.PriceCouponClaimRecordMapper; +import com.ycwl.basic.pricing.mapper.PriceCouponConfigMapper; +import com.ycwl.basic.pricing.service.ICouponManagementService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 优惠券管理服务实现(管理端) + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class CouponManagementServiceImpl implements ICouponManagementService { + + private final PriceCouponConfigMapper couponConfigMapper; + private final PriceCouponClaimRecordMapper claimRecordMapper; + + // ==================== 优惠券配置管理 ==================== + + @Override + @Transactional + public Long createCouponConfig(PriceCouponConfig config) { + log.info("创建优惠券配置: {}", config.getCouponName()); + + // 设置默认值 + if (config.getUsedQuantity() == null) { + config.setUsedQuantity(0); + } + if (config.getIsActive() == null) { + config.setIsActive(true); + } + + int result = couponConfigMapper.insertCoupon(config); + if (result > 0) { + log.info("优惠券配置创建成功,ID: {}", config.getId()); + return config.getId(); + } else { + log.error("优惠券配置创建失败"); + return null; + } + } + + @Override + @Transactional + public boolean updateCouponConfig(PriceCouponConfig config) { + log.info("更新优惠券配置,ID: {}", config.getId()); + + PriceCouponConfig existing = couponConfigMapper.selectById(config.getId()); + if (existing == null) { + log.error("优惠券配置不存在,ID: {}", config.getId()); + return false; + } + + int result = couponConfigMapper.updateCoupon(config); + if (result > 0) { + log.info("优惠券配置更新成功,ID: {}", config.getId()); + return true; + } else { + log.error("优惠券配置更新失败,ID: {}", config.getId()); + return false; + } + } + + @Override + @Transactional + public boolean deleteCouponConfig(Long id) { + log.info("删除优惠券配置,ID: {}", id); + + PriceCouponConfig existing = couponConfigMapper.selectById(id); + if (existing == null) { + log.error("优惠券配置不存在,ID: {}", id); + return false; + } + + int result = couponConfigMapper.deleteCoupon(id); + if (result > 0) { + log.info("优惠券配置删除成功,ID: {}", id); + return true; + } else { + log.error("优惠券配置删除失败,ID: {}", id); + return false; + } + } + + @Override + @Transactional + public boolean updateCouponConfigStatus(Long id, Boolean isActive) { + log.info("更新优惠券配置状态,ID: {}, 状态: {}", id, isActive); + + PriceCouponConfig existing = couponConfigMapper.selectById(id); + if (existing == null) { + log.error("优惠券配置不存在,ID: {}", id); + return false; + } + + int result = couponConfigMapper.updateCouponStatus(id, isActive); + if (result > 0) { + log.info("优惠券配置状态更新成功,ID: {}", id); + return true; + } else { + log.error("优惠券配置状态更新失败,ID: {}", id); + return false; + } + } + + @Override + public List getAllCouponConfigs() { + log.info("查询所有优惠券配置"); + return couponConfigMapper.selectAllForAdmin(); + } + + @Override + public PageInfo getCouponConfigsPage(Integer pageNum, Integer pageSize, + Boolean isActive, String couponName) { + log.info("分页查询优惠券配置,页码: {}, 页大小: {}, 状态: {}, 名称: {}", + pageNum, pageSize, isActive, couponName); + + PageHelper.startPage(pageNum, pageSize); + List configs = couponConfigMapper.selectByConditionsForAdmin(isActive, couponName); + return new PageInfo<>(configs); + } + + @Override + public List getCouponConfigsByStatus(Boolean isActive) { + log.info("根据状态查询优惠券配置,状态: {}", isActive); + return couponConfigMapper.selectByStatusForAdmin(isActive); + } + + @Override + public PriceCouponConfig getCouponConfigById(Long id) { + log.info("根据ID查询优惠券配置,ID: {}", id); + return couponConfigMapper.selectById(id); + } + + // ==================== 优惠券领取记录查询 ==================== + + @Override + public List getAllClaimRecords() { + log.info("查询所有优惠券领取记录"); + return claimRecordMapper.selectAllForAdmin(); + } + + @Override + public PageInfo getClaimRecordsPage(Integer pageNum, Integer pageSize, + Long userId, Long couponId, CouponStatus status, + String startTime, String endTime) { + log.info("分页查询优惠券领取记录,页码: {}, 页大小: {}, 用户ID: {}, 优惠券ID: {}, 状态: {}, 开始时间: {}, 结束时间: {}", + pageNum, pageSize, userId, couponId, status, startTime, endTime); + + PageHelper.startPage(pageNum, pageSize); + List records = claimRecordMapper.selectByConditionsForAdmin(userId, couponId, status, startTime, endTime); + return new PageInfo<>(records); + } + + @Override + public List getClaimRecordsByUserId(Long userId) { + log.info("根据用户ID查询优惠券领取记录,用户ID: {}", userId); + return claimRecordMapper.selectByUserIdForAdmin(userId); + } + + @Override + public List getClaimRecordsByCouponId(Long couponId) { + log.info("根据优惠券ID查询领取记录,优惠券ID: {}", couponId); + return claimRecordMapper.selectByCouponIdForAdmin(couponId); + } + + @Override + public List getClaimRecordsByStatus(CouponStatus status) { + log.info("根据状态查询领取记录,状态: {}", status); + return claimRecordMapper.selectByStatusForAdmin(status); + } + + @Override + public Map getCouponUsageStats(Long couponId) { + log.info("查询优惠券使用统计,优惠券ID: {}", couponId); + return claimRecordMapper.selectCouponUsageStats(couponId); + } + + @Override + public Map getCouponDetailStats(Long couponId) { + log.info("查询优惠券详细统计,优惠券ID: {}", couponId); + return claimRecordMapper.selectCouponDetailStats(couponId); + } + + @Override + public Map getPeriodStats(String startDate, String endDate) { + log.info("查询时间范围统计,开始日期: {}, 结束日期: {}", startDate, endDate); + return claimRecordMapper.selectPeriodStats(startDate, endDate); + } + + @Override + public List> getAllCouponUsageOverview() { + log.info("查询所有优惠券使用统计概览"); + + List allCoupons = couponConfigMapper.selectAllForAdmin(); + List> overview = new ArrayList<>(); + + for (PriceCouponConfig coupon : allCoupons) { + Map stats = new HashMap<>(); + stats.put("couponId", coupon.getId()); + stats.put("couponName", coupon.getCouponName()); + stats.put("couponType", coupon.getCouponType()); + stats.put("totalQuantity", coupon.getTotalQuantity()); + stats.put("usedQuantity", coupon.getUsedQuantity()); + stats.put("remainingQuantity", coupon.getTotalQuantity() - coupon.getUsedQuantity()); + stats.put("isActive", coupon.getIsActive()); + stats.put("validFrom", coupon.getValidFrom()); + stats.put("validUntil", coupon.getValidUntil()); + + // 获取详细统计 + Map usageStats = claimRecordMapper.selectCouponUsageStats(coupon.getId()); + stats.putAll(usageStats); + + overview.add(stats); + } + + return overview; + } +} \ No newline at end of file