兑换码优化

This commit is contained in:
张松
2025-10-22 11:07:53 +08:00
parent f210284292
commit ca68666a36
28 changed files with 215 additions and 903 deletions

View File

@@ -3,19 +3,17 @@ package com.czg.controller.admin;
import com.czg.annotation.SaAdminCheckPermission; import com.czg.annotation.SaAdminCheckPermission;
import com.czg.annotation.SaCheckMainShop; import com.czg.annotation.SaCheckMainShop;
import com.czg.constant.TableValueConstant; import com.czg.constant.TableValueConstant;
import com.czg.market.dto.MkCouponRedemptionConfigDTO; import com.czg.market.dto.MkRedemptionConfigDTO;
import com.czg.market.dto.MkEnableConfigDTO; import com.czg.market.dto.MkEnableConfigDTO;
import com.czg.market.entity.MkCouponRedemptionConfig; import com.czg.market.service.MkRedemptionConfigService;
import com.czg.market.service.MkCouponRedemptionConfigService;
import com.czg.market.service.MkEnableConfigService; import com.czg.market.service.MkEnableConfigService;
import com.czg.market.vo.MkCouponRedemptionCodeVO; import com.czg.market.vo.MkRedemptionCodeVO;
import com.czg.market.vo.MkCouponRedemptionConfigVO; import com.czg.market.vo.MkRedemptionConfigVO;
import com.czg.market.vo.MkEnableConfigVO; import com.czg.market.vo.MkEnableConfigVO;
import com.czg.resp.CzgResult; import com.czg.resp.CzgResult;
import com.czg.sa.StpKit; import com.czg.sa.StpKit;
import com.czg.validator.group.UpdateGroup; import com.czg.validator.group.UpdateGroup;
import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
@@ -32,7 +30,7 @@ import org.springframework.web.bind.annotation.*;
@RequestMapping("/admin/couponRedemption") @RequestMapping("/admin/couponRedemption")
public class CouponRedemptionController { public class CouponRedemptionController {
@Resource @Resource
private MkCouponRedemptionConfigService configService; private MkRedemptionConfigService configService;
@Resource @Resource
private MkEnableConfigService enableConfigService; private MkEnableConfigService enableConfigService;
@@ -58,7 +56,7 @@ public class CouponRedemptionController {
*/ */
@SaAdminCheckPermission(value = "couponRedemption:detail", name = "券兑换码列表") @SaAdminCheckPermission(value = "couponRedemption:detail", name = "券兑换码列表")
@GetMapping @GetMapping
public CzgResult<MkCouponRedemptionConfigVO> detail(@RequestParam Long id) { public CzgResult<MkRedemptionConfigVO> detail(@RequestParam Long id) {
return CzgResult.success(configService.detail(StpKit.USER.getMainShopId(), id)); return CzgResult.success(configService.detail(StpKit.USER.getMainShopId(), id));
} }
@@ -67,8 +65,8 @@ public class CouponRedemptionController {
*/ */
@SaAdminCheckPermission(value = "couponRedemption:list", name = "券兑换码列表") @SaAdminCheckPermission(value = "couponRedemption:list", name = "券兑换码列表")
@GetMapping("/list") @GetMapping("/list")
public CzgResult<Page<MkCouponRedemptionConfigVO>> list(@RequestParam(required = false, defaultValue = "-1") Integer status) { public CzgResult<Page<MkRedemptionConfigVO>> list(@RequestParam(required = false, defaultValue = "-1") Integer status) {
return CzgResult.success(configService.pageInfo(StpKit.USER.getMainShopId(), status)); return CzgResult.success(configService.pageInfo(StpKit.USER.getMainShopId(), status, false));
} }
/** /**
@@ -77,8 +75,8 @@ public class CouponRedemptionController {
@SaAdminCheckPermission(value = "couponRedemption:add", name = "券兑换码配置添加") @SaAdminCheckPermission(value = "couponRedemption:add", name = "券兑换码配置添加")
@PostMapping @PostMapping
@SaCheckMainShop @SaCheckMainShop
public CzgResult<Boolean> add(@Validated @RequestBody MkCouponRedemptionConfigDTO dto) { public CzgResult<Boolean> add(@Validated @RequestBody MkRedemptionConfigDTO dto) {
return CzgResult.success(configService.add(StpKit.USER.getMainShopId(), dto)); return CzgResult.success(configService.add(StpKit.USER.getMainShopId(), dto, false));
} }
/** /**
@@ -89,8 +87,8 @@ public class CouponRedemptionController {
@SaAdminCheckPermission(value = "couponRedemption:edit", name = "券兑换码修改") @SaAdminCheckPermission(value = "couponRedemption:edit", name = "券兑换码修改")
@SaCheckMainShop @SaCheckMainShop
@PutMapping @PutMapping
public CzgResult<Boolean> edit(@Validated({UpdateGroup.class, Default.class}) @RequestBody MkCouponRedemptionConfigDTO dto) { public CzgResult<Boolean> edit(@Validated({UpdateGroup.class, Default.class}) @RequestBody MkRedemptionConfigDTO dto) {
return CzgResult.success(configService.edit(StpKit.USER.getShopId(), dto)); return CzgResult.success(configService.edit(StpKit.USER.getShopId(), dto, false));
} }
/** /**
@@ -100,8 +98,8 @@ public class CouponRedemptionController {
*/ */
@SaAdminCheckPermission(value = "couponRedemption:codeList", name = "券兑换码码列表") @SaAdminCheckPermission(value = "couponRedemption:codeList", name = "券兑换码码列表")
@GetMapping("/code/list") @GetMapping("/code/list")
public CzgResult<Page<MkCouponRedemptionCodeVO>> codeList(@RequestParam Long redemptionId, @RequestParam(required = false) String code, @RequestParam(required = false) Integer status) { public CzgResult<Page<MkRedemptionCodeVO>> codeList(@RequestParam Long redemptionId, @RequestParam(required = false) String code, @RequestParam(required = false) Integer status) {
return CzgResult.success(configService.codeList(StpKit.USER.getMainShopId(), redemptionId, code, status)); return CzgResult.success(configService.codeList(StpKit.USER.getMainShopId(), redemptionId, code, status, false));
} }
/** /**
@@ -111,7 +109,7 @@ public class CouponRedemptionController {
@GetMapping("/code/export") @GetMapping("/code/export")
public void exportCodeList(@RequestParam Long redemptionId, @RequestParam(required = false) String code, @RequestParam(required = false) Integer status, public void exportCodeList(@RequestParam Long redemptionId, @RequestParam(required = false) String code, @RequestParam(required = false) Integer status,
HttpServletResponse response, HttpServletRequest request) { HttpServletResponse response, HttpServletRequest request) {
configService.exportCodeList(StpKit.USER.getMainShopId(), redemptionId, code, status, response, request); configService.exportCodeList(StpKit.USER.getMainShopId(), redemptionId, code, status, response, request, false);
} }
} }

View File

@@ -3,19 +3,17 @@ package com.czg.controller.admin;
import com.czg.annotation.SaAdminCheckPermission; import com.czg.annotation.SaAdminCheckPermission;
import com.czg.annotation.SaCheckMainShop; import com.czg.annotation.SaCheckMainShop;
import com.czg.constant.TableValueConstant; import com.czg.constant.TableValueConstant;
import com.czg.market.dto.MkRedemptionConfigDTO;
import com.czg.market.dto.MkEnableConfigDTO; import com.czg.market.dto.MkEnableConfigDTO;
import com.czg.market.dto.MkRechargeRedemptionConfigDTO; import com.czg.market.service.MkRedemptionConfigService;
import com.czg.market.entity.MkRechargeRedemptionConfig;
import com.czg.market.service.MkEnableConfigService; import com.czg.market.service.MkEnableConfigService;
import com.czg.market.service.MkRechargeRedemptionConfigService; import com.czg.market.vo.MkRedemptionCodeVO;
import com.czg.market.vo.MkRedemptionConfigVO;
import com.czg.market.vo.MkEnableConfigVO; import com.czg.market.vo.MkEnableConfigVO;
import com.czg.market.vo.MkRechargeRedemptionCodeVO;
import com.czg.market.vo.MkRechargeRedemptionConfigVO;
import com.czg.resp.CzgResult; import com.czg.resp.CzgResult;
import com.czg.sa.StpKit; import com.czg.sa.StpKit;
import com.czg.validator.group.UpdateGroup; import com.czg.validator.group.UpdateGroup;
import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
@@ -32,7 +30,7 @@ import org.springframework.web.bind.annotation.*;
@RequestMapping("/admin/rechargeRedemption") @RequestMapping("/admin/rechargeRedemption")
public class RechargeRedemptionController { public class RechargeRedemptionController {
@Resource @Resource
private MkRechargeRedemptionConfigService configService; private MkRedemptionConfigService configService;
@Resource @Resource
private MkEnableConfigService enableConfigService; private MkEnableConfigService enableConfigService;
@@ -58,9 +56,8 @@ public class RechargeRedemptionController {
*/ */
@SaAdminCheckPermission(value = "rechargeRedemption:detail", name = "充值兑换列表") @SaAdminCheckPermission(value = "rechargeRedemption:detail", name = "充值兑换列表")
@GetMapping @GetMapping
public CzgResult<MkRechargeRedemptionConfigVO> detail(@RequestParam Integer id) { public CzgResult<MkRedemptionConfigVO> detail(@RequestParam Long id) {
return CzgResult.success(configService.getOneAs(new QueryWrapper().eq(MkRechargeRedemptionConfig::getId, id) return CzgResult.success(configService.detail(StpKit.USER.getMainShopId(), id));
.eq(MkRechargeRedemptionConfig::getMainShopId, StpKit.USER.getMainShopId()), MkRechargeRedemptionConfigVO.class));
} }
/** /**
@@ -68,8 +65,8 @@ public class RechargeRedemptionController {
*/ */
@SaAdminCheckPermission(value = "rechargeRedemption:list", name = "充值兑换列表") @SaAdminCheckPermission(value = "rechargeRedemption:list", name = "充值兑换列表")
@GetMapping("/list") @GetMapping("/list")
public CzgResult<Page<MkRechargeRedemptionConfig>> list(@RequestParam(required = false, defaultValue = "-1") Integer status) { public CzgResult<Page<MkRedemptionConfigVO>> list(@RequestParam(required = false, defaultValue = "-1") Integer status) {
return CzgResult.success(configService.pageInfo(StpKit.USER.getMainShopId(), status)); return CzgResult.success(configService.pageInfo(StpKit.USER.getMainShopId(), status, true));
} }
/** /**
@@ -78,8 +75,8 @@ public class RechargeRedemptionController {
@SaAdminCheckPermission(value = "rechargeRedemption:add", name = "充值兑换配置添加") @SaAdminCheckPermission(value = "rechargeRedemption:add", name = "充值兑换配置添加")
@PostMapping @PostMapping
@SaCheckMainShop @SaCheckMainShop
public CzgResult<Boolean> add(@Validated @RequestBody MkRechargeRedemptionConfigDTO dto) { public CzgResult<Boolean> add(@Validated @RequestBody MkRedemptionConfigDTO dto) {
return CzgResult.success(configService.add(StpKit.USER.getMainShopId(), dto)); return CzgResult.success(configService.add(StpKit.USER.getMainShopId(), dto, true));
} }
/** /**
@@ -90,8 +87,8 @@ public class RechargeRedemptionController {
@SaAdminCheckPermission(value = "rechargeRedemption:edit", name = "充值兑换修改") @SaAdminCheckPermission(value = "rechargeRedemption:edit", name = "充值兑换修改")
@SaCheckMainShop @SaCheckMainShop
@PutMapping @PutMapping
public CzgResult<Boolean> edit(@Validated({UpdateGroup.class, Default.class}) @RequestBody MkRechargeRedemptionConfigDTO dto) { public CzgResult<Boolean> edit(@Validated({UpdateGroup.class, Default.class}) @RequestBody MkRedemptionConfigDTO dto) {
return CzgResult.success(configService.edit(StpKit.USER.getShopId(), dto)); return CzgResult.success(configService.edit(StpKit.USER.getShopId(), dto, true));
} }
/** /**
@@ -101,8 +98,8 @@ public class RechargeRedemptionController {
*/ */
@SaAdminCheckPermission(value = "rechargeRedemption:codeList", name = "充值兑换码列表") @SaAdminCheckPermission(value = "rechargeRedemption:codeList", name = "充值兑换码列表")
@GetMapping("/code/list") @GetMapping("/code/list")
public CzgResult<Page<MkRechargeRedemptionCodeVO>> codeList(@RequestParam Long redemptionId, @RequestParam(required = false) String code, @RequestParam(required = false) Integer status) { public CzgResult<Page<MkRedemptionCodeVO>> codeList(@RequestParam Long redemptionId, @RequestParam(required = false) String code, @RequestParam(required = false) Integer status) {
return CzgResult.success(configService.codeList(StpKit.USER.getMainShopId(), redemptionId, code, status)); return CzgResult.success(configService.codeList(StpKit.USER.getMainShopId(), redemptionId, code, status, true));
} }
/** /**
@@ -112,7 +109,7 @@ public class RechargeRedemptionController {
@GetMapping("/code/export") @GetMapping("/code/export")
public void exportCodeList(@RequestParam Long redemptionId, @RequestParam(required = false) String code, @RequestParam(required = false) Integer status, public void exportCodeList(@RequestParam Long redemptionId, @RequestParam(required = false) String code, @RequestParam(required = false) Integer status,
HttpServletResponse response, HttpServletRequest request) { HttpServletResponse response, HttpServletRequest request) {
configService.exportCodeList(StpKit.USER.getMainShopId(), redemptionId, code, status, response, request); configService.exportCodeList(StpKit.USER.getMainShopId(), redemptionId, code, status, response, request, true);
} }
} }

View File

@@ -1,9 +1,7 @@
package com.czg.controller.user; package com.czg.controller.user;
import com.czg.market.dto.MkRedemptionDTO; import com.czg.market.dto.MkRedemptionDTO;
import com.czg.market.service.MkCouponRedemptionConfigService; import com.czg.market.service.MkRedemptionConfigService;
import com.czg.market.service.MkEnableConfigService;
import com.czg.market.service.MkRechargeRedemptionConfigService;
import com.czg.resp.CzgResult; import com.czg.resp.CzgResult;
import com.czg.sa.StpKit; import com.czg.sa.StpKit;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
@@ -19,20 +17,15 @@ import org.springframework.web.bind.annotation.*;
@RequestMapping("/user/redemption") @RequestMapping("/user/redemption")
public class URedemptionController { public class URedemptionController {
@Resource @Resource
private MkRechargeRedemptionConfigService rechargeRedemptionConfigService; private MkRedemptionConfigService couponRedemptionConfigService;
@Resource
private MkCouponRedemptionConfigService couponRedemptionConfigService;
/** /**
* 使用券码 * 使用券码
*/ */
@PostMapping("/exchange") @PostMapping("/exchange")
public CzgResult<Boolean> exchange(@Validated @RequestBody MkRedemptionDTO dto) { public CzgResult<Boolean> exchange(@Validated @RequestBody MkRedemptionDTO dto) {
if ("recharge".equals(dto.getType())) { couponRedemptionConfigService.exchange(StpKit.USER.getLoginIdAsLong(), dto);
rechargeRedemptionConfigService.exchange(StpKit.USER.getLoginIdAsLong(), dto);
}else {
couponRedemptionConfigService.exchange(StpKit.USER.getLoginIdAsLong(), dto);
}
return CzgResult.success(); return CzgResult.success();
} }

View File

@@ -1,66 +0,0 @@
package com.czg.market.dto;
import com.czg.market.entity.ShopCoupon;
import com.czg.validator.group.UpdateGroup;
import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import jakarta.validation.Valid;
import jakarta.validation.constraints.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
/**
* @author Administrator
*/
@Data
public class MkRechargeRedemptionConfigDTO implements Serializable {
@NotNull(message = "id不能为空", groups = UpdateGroup.class)
private Long id;
/**
* 名称
*/
@NotBlank(message = "名称不能为空")
private String name;
/**
* 赠送金额
*/
@NotNull(message = "赠送金额不能为空")
@DecimalMin(value = "0.01", message = "赠送金额不能小于0.01")
private BigDecimal amount;
/**
* 库存
*/
private Integer stock;
/**
* 总数
*/
@Min(value = 0, message = "总数不能小于0")
@NotNull(message = "总数不能为空")
@Max(value = 1000, message = "总数不能大于1000")
private Integer total;
/**
* 可用开始时间
*/
private LocalDateTime startTime;
/**
* 可用结束时间
*/
private LocalDateTime endTime;
}

View File

@@ -14,7 +14,7 @@ import java.util.List;
* @author Administrator * @author Administrator
*/ */
@Data @Data
public class MkCouponRedemptionConfigDTO implements Serializable { public class MkRedemptionConfigDTO implements Serializable {
@NotNull(message = "id不能为空", groups = UpdateGroup.class) @NotNull(message = "id不能为空", groups = UpdateGroup.class)
@@ -26,6 +26,12 @@ public class MkCouponRedemptionConfigDTO implements Serializable {
@NotBlank(message = "名称不能为空") @NotBlank(message = "名称不能为空")
private String name; private String name;
/**
* 赠送金额
*/
@DecimalMin(value = "0.01", message = "赠送金额不能小于0.01")
private BigDecimal amount;
/** /**
* 券信息 * 券信息
*/ */

View File

@@ -1,85 +0,0 @@
package com.czg.market.entity;
import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.io.Serial;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
/**
* 兑换码明细 实体类。
*
* @author zs
* @since 2025-10-21
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table("mk_recharge_redemption_code")
@Accessors(chain = true)
public class MkRechargeRedemptionCode implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Id(keyType = KeyType.Auto)
private Long id;
/**
* 兑换配置id
*/
private Long redemptionId;
/**
* 主店id
*/
private Long mainShopId;
/**
* 兑换时间
*/
private LocalDateTime redemptionTime;
/**
* 0未兑换 1已兑换
*/
private Integer status;
/**
* 店铺用户id
*/
private Long shopUserId;
/**
* 用户id
*/
private Long userId;
/**
* 创建时间
*/
@Column(onInsertValue = "now()")
private LocalDateTime createTime;
/**
* 修改时间
*/
@Column(onInsertValue = "now()", onUpdateValue = "now()")
private LocalDateTime updateTime;
/**
* 兑换码
*/
private String code;
}

View File

@@ -1,88 +0,0 @@
package com.czg.market.entity;
import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.io.Serial;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
/**
* 充值优惠券修改 实体类。
*
* @author zs
* @since 2025-10-21
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table("mk_recharge_redemption_config")
@Accessors(chain = true)
public class MkRechargeRedemptionConfig implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Id(keyType = KeyType.Auto)
private Long id;
/**
* 名称
*/
private String name;
/**
* 赠送金额
*/
private BigDecimal amount;
/**
* 库存
*/
private Integer stock;
/**
* 总数
*/
private Integer total;
/**
* 可用开始时间
*/
private LocalDateTime startTime;
/**
* 可用结束时间
*/
private LocalDateTime endTime;
/**
* 门店id
*/
private Long mainShopId;
/**
* 创建时间
*/
@Column(onInsertValue = "now()")
private LocalDateTime createTime;
/**
* 修改时间
*/
@Column(onInsertValue = "now()", onUpdateValue = "now()")
private LocalDateTime updateTime;
@Column(ignore = true)
private Integer status;
}

View File

@@ -25,9 +25,9 @@ import lombok.experimental.Accessors;
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@Table("mk_coupon_redemption_code") @Table("mk_redemption_code")
@Accessors(chain = true) @Accessors(chain = true)
public class MkCouponRedemptionCode implements Serializable { public class MkRedemptionCode implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;

View File

@@ -9,7 +9,6 @@ import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.io.Serial; import java.io.Serial;
import java.util.List;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
@@ -26,8 +25,8 @@ import lombok.NoArgsConstructor;
@Builder @Builder
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@Table("mk_coupon_redemption_config") @Table("mk_redemption_config")
public class MkCouponRedemptionConfig implements Serializable { public class MkRedemptionConfig implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@@ -40,6 +39,8 @@ public class MkCouponRedemptionConfig implements Serializable {
*/ */
private String name; private String name;
private BigDecimal amount;
/** /**
* 券信息 * 券信息
@@ -89,4 +90,6 @@ public class MkCouponRedemptionConfig implements Serializable {
@Column(ignore = true) @Column(ignore = true)
private int status; private int status;
private Integer type;
} }

View File

@@ -1,33 +0,0 @@
package com.czg.market.service;
import com.czg.market.dto.MkCouponRedemptionConfigDTO;
import com.czg.market.dto.MkRedemptionDTO;
import com.czg.market.vo.MkCouponRedemptionCodeVO;
import com.czg.market.vo.MkCouponRedemptionConfigVO;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.service.IService;
import com.czg.market.entity.MkCouponRedemptionConfig;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
/**
* 充值优惠券修改 服务层。
*
* @author zs
* @since 2025-10-22
*/
public interface MkCouponRedemptionConfigService extends IService<MkCouponRedemptionConfig> {
MkCouponRedemptionConfigVO detail(Long mainShopId, Long id);
Boolean edit(Long shopId, MkCouponRedemptionConfigDTO dto);
boolean add(Long mainShopId, MkCouponRedemptionConfigDTO dto);
Page<MkCouponRedemptionConfigVO> pageInfo(Long mainShopId, Integer status);
Page<MkCouponRedemptionCodeVO> codeList(Long mainShopId, Long id, String code, Integer status);
void exportCodeList(Long mainShopId, Long redemptionId, String code, Integer status, HttpServletResponse response, HttpServletRequest request);
void exchange(long userId, MkRedemptionDTO dto);
}

View File

@@ -1,14 +0,0 @@
package com.czg.market.service;
import com.mybatisflex.core.service.IService;
import com.czg.market.entity.MkRechargeRedemptionCode;
/**
* 兑换码明细 服务层。
*
* @author zs
* @since 2025-10-21
*/
public interface MkRechargeRedemptionCodeService extends IService<MkRechargeRedemptionCode> {
}

View File

@@ -1,34 +0,0 @@
package com.czg.market.service;
import com.czg.market.dto.MkRechargeRedemptionConfigDTO;
import com.czg.market.dto.MkRedemptionDTO;
import com.czg.market.vo.MkRechargeRedemptionCodeVO;
import com.czg.market.vo.MkRechargeRedemptionConfigVO;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.service.IService;
import com.czg.market.entity.MkRechargeRedemptionConfig;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
/**
* 充值优惠券修改 服务层。
*
* @author zs
* @since 2025-10-21
*/
public interface MkRechargeRedemptionConfigService extends IService<MkRechargeRedemptionConfig> {
MkRechargeRedemptionConfigVO detail(Long mainShopId);
Boolean edit(Long shopId, MkRechargeRedemptionConfigDTO dto);
boolean add(Long mainShopId, MkRechargeRedemptionConfigDTO dto);
Page<MkRechargeRedemptionConfig> pageInfo(Long mainShopId, Integer status);
Page<MkRechargeRedemptionCodeVO> codeList(Long mainShopId, Long id, String code, Integer status);
void exportCodeList(Long mainShopId, Long redemptionId, String code, Integer status, HttpServletResponse response, HttpServletRequest request);
void exchange(long userId, MkRedemptionDTO dto);
}

View File

@@ -1,7 +1,7 @@
package com.czg.market.service; package com.czg.market.service;
import com.mybatisflex.core.service.IService; import com.mybatisflex.core.service.IService;
import com.czg.market.entity.MkCouponRedemptionCode; import com.czg.market.entity.MkRedemptionCode;
/** /**
* 兑换码明细 服务层 * 兑换码明细 服务层
@@ -9,6 +9,6 @@ import com.czg.market.entity.MkCouponRedemptionCode;
* @author zs * @author zs
* @since 2025-10-22 * @since 2025-10-22
*/ */
public interface MkCouponRedemptionCodeService extends IService<MkCouponRedemptionCode> { public interface MkRedemptionCodeService extends IService<MkRedemptionCode> {
} }

View File

@@ -0,0 +1,33 @@
package com.czg.market.service;
import com.czg.market.dto.MkRedemptionConfigDTO;
import com.czg.market.dto.MkRedemptionDTO;
import com.czg.market.vo.MkRedemptionCodeVO;
import com.czg.market.vo.MkRedemptionConfigVO;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.service.IService;
import com.czg.market.entity.MkRedemptionConfig;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
/**
* 充值优惠券修改 服务层。
*
* @author zs
* @since 2025-10-22
*/
public interface MkRedemptionConfigService extends IService<MkRedemptionConfig> {
MkRedemptionConfigVO detail(Long mainShopId, Long id);
Boolean edit(Long shopId, MkRedemptionConfigDTO dto, boolean isRecharge);
boolean add(Long mainShopId, MkRedemptionConfigDTO dto, boolean isRecharge);
Page<MkRedemptionConfigVO> pageInfo(Long mainShopId, Integer status, boolean isRecharge);
Page<MkRedemptionCodeVO> codeList(Long mainShopId, Long id, String code, Integer status, boolean isRecharge);
void exportCodeList(Long mainShopId, Long redemptionId, String code, Integer status, HttpServletResponse response, HttpServletRequest request, boolean isRecharge);
void exchange(long userId, MkRedemptionDTO dto);
}

View File

@@ -1,89 +0,0 @@
package com.czg.market.vo;
import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 兑换码明细 实体类。
*
* @author zs
* @since 2025-10-21
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class MkRechargeRedemptionCodeVO implements Serializable {
@Id(keyType = KeyType.Auto)
private Long id;
/**
* 兑换配置id
*/
private Long redemptionId;
/**
* 主店id
*/
private Long mainShopId;
/**
* 兑换时间
*/
private LocalDateTime redemptionTime;
/**
* 0未兑换 1已兑换
*/
private Integer status;
/**
* 店铺用户id
*/
private Long shopUserId;
/**
* 用户id
*/
private Long userId;
/**
* 创建时间
*/
@Column(onInsertValue = "now()")
private LocalDateTime createTime;
/**
* 修改时间
*/
@Column(onInsertValue = "now()", onUpdateValue = "now()")
private LocalDateTime updateTime;
/**
* 兑换码
*/
private String code;
/**
* 用户昵称
*/
private String nickName;
/**
* 用户手机号
*/
private String phone;
}

View File

@@ -1,25 +0,0 @@
package com.czg.market.vo;
import com.czg.market.dto.MemberConfigDTO;
import com.czg.market.entity.MkRechargeRedemptionConfig;
import jakarta.validation.Valid;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
/**
* @author Administrator
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class MkRechargeRedemptionConfigVO extends MkRechargeRedemptionConfig implements Serializable {
}

View File

@@ -23,7 +23,7 @@ import java.time.LocalDateTime;
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@Accessors(chain = true) @Accessors(chain = true)
public class MkCouponRedemptionCodeVO implements Serializable { public class MkRedemptionCodeVO implements Serializable {
@Id(keyType = KeyType.Auto) @Id(keyType = KeyType.Auto)
private Long id; private Long id;

View File

@@ -1,12 +1,10 @@
package com.czg.market.vo; package com.czg.market.vo;
import com.czg.market.dto.CouponInfoDTO; import com.czg.market.dto.CouponInfoDTO;
import com.czg.market.entity.MkRechargeRedemptionConfig;
import com.mybatisflex.annotation.Column; import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id; import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType; import com.mybatisflex.annotation.KeyType;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
@@ -18,7 +16,7 @@ import java.util.List;
* @author Administrator * @author Administrator
*/ */
@Data @Data
public class MkCouponRedemptionConfigVO implements Serializable { public class MkRedemptionConfigVO implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@@ -78,4 +76,7 @@ public class MkCouponRedemptionConfigVO implements Serializable {
@Column(ignore = true) @Column(ignore = true)
private Integer status; private Integer status;
private BigDecimal amount;
private Integer type;
} }

View File

@@ -1,7 +1,7 @@
package com.czg.service.market.mapper; package com.czg.service.market.mapper;
import com.mybatisflex.core.BaseMapper; import com.mybatisflex.core.BaseMapper;
import com.czg.market.entity.MkCouponRedemptionCode; import com.czg.market.entity.MkRedemptionCode;
/** /**
* 兑换码明细 映射层。 * 兑换码明细 映射层。
@@ -9,6 +9,6 @@ import com.czg.market.entity.MkCouponRedemptionCode;
* @author zs * @author zs
* @since 2025-10-22 * @since 2025-10-22
*/ */
public interface MkCouponRedemptionCodeMapper extends BaseMapper<MkCouponRedemptionCode> { public interface MkCouponRedemptionCodeMapper extends BaseMapper<MkRedemptionCode> {
} }

View File

@@ -1,7 +1,7 @@
package com.czg.service.market.mapper; package com.czg.service.market.mapper;
import com.mybatisflex.core.BaseMapper; import com.mybatisflex.core.BaseMapper;
import com.czg.market.entity.MkCouponRedemptionConfig; import com.czg.market.entity.MkRedemptionConfig;
/** /**
* 充值优惠券修改 映射层。 * 充值优惠券修改 映射层。
@@ -9,6 +9,6 @@ import com.czg.market.entity.MkCouponRedemptionConfig;
* @author zs * @author zs
* @since 2025-10-22 * @since 2025-10-22
*/ */
public interface MkCouponRedemptionConfigMapper extends BaseMapper<MkCouponRedemptionConfig> { public interface MkCouponRedemptionConfigMapper extends BaseMapper<MkRedemptionConfig> {
} }

View File

@@ -1,14 +0,0 @@
package com.czg.service.market.mapper;
import com.mybatisflex.core.BaseMapper;
import com.czg.market.entity.MkRechargeRedemptionCode;
/**
* 兑换码明细 映射层。
*
* @author zs
* @since 2025-10-21
*/
public interface MkRechargeRedemptionCodeMapper extends BaseMapper<MkRechargeRedemptionCode> {
}

View File

@@ -1,14 +0,0 @@
package com.czg.service.market.mapper;
import com.mybatisflex.core.BaseMapper;
import com.czg.market.entity.MkRechargeRedemptionConfig;
/**
* 充值优惠券修改 映射层。
*
* @author zs
* @since 2025-10-21
*/
public interface MkRechargeRedemptionConfigMapper extends BaseMapper<MkRechargeRedemptionConfig> {
}

View File

@@ -1,8 +1,8 @@
package com.czg.service.market.service.impl; package com.czg.service.market.service.impl;
import com.mybatisflex.spring.service.impl.ServiceImpl; import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.czg.market.entity.MkCouponRedemptionCode; import com.czg.market.entity.MkRedemptionCode;
import com.czg.market.service.MkCouponRedemptionCodeService; import com.czg.market.service.MkRedemptionCodeService;
import com.czg.service.market.mapper.MkCouponRedemptionCodeMapper; import com.czg.service.market.mapper.MkCouponRedemptionCodeMapper;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -13,6 +13,6 @@ import org.springframework.stereotype.Service;
* @since 2025-10-22 * @since 2025-10-22
*/ */
@Service @Service
public class MkCouponRedemptionCodeServiceImpl extends ServiceImpl<MkCouponRedemptionCodeMapper, MkCouponRedemptionCode> implements MkCouponRedemptionCodeService{ public class MkCouponRedemptionCodeServiceImpl extends ServiceImpl<MkCouponRedemptionCodeMapper, MkRedemptionCode> implements MkRedemptionCodeService {
} }

View File

@@ -1,271 +0,0 @@
package com.czg.service.market.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.fastjson2.JSONArray;
import com.czg.account.dto.shopuser.ShopUserMoneyEditDTO;
import com.czg.account.entity.ShopUser;
import com.czg.account.service.ShopInfoService;
import com.czg.account.service.ShopUserService;
import com.czg.constant.TableValueConstant;
import com.czg.enums.ShopUserFlowBizEnum;
import com.czg.exception.CzgException;
import com.czg.market.dto.CouponInfoDTO;
import com.czg.market.dto.MkCouponRedemptionConfigDTO;
import com.czg.market.dto.MkRedemptionDTO;
import com.czg.market.dto.MkShopCouponGiftDTO;
import com.czg.market.entity.MkCouponRedemptionCode;
import com.czg.market.entity.MkCouponRedemptionConfig;
import com.czg.market.entity.MkRechargeRedemptionCode;
import com.czg.market.entity.MkRechargeRedemptionConfig;
import com.czg.market.service.MkCouponRedemptionCodeService;
import com.czg.market.service.MkEnableConfigService;
import com.czg.market.service.MkShopCouponRecordService;
import com.czg.market.vo.CouponInfoVO;
import com.czg.market.vo.MkCouponRedemptionConfigVO;
import com.czg.market.vo.MkCouponRedemptionCodeVO;
import com.czg.utils.AssertUtil;
import com.czg.utils.MyQueryWrapper;
import com.czg.utils.PageUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.czg.market.service.MkCouponRedemptionConfigService;
import com.czg.service.market.mapper.MkCouponRedemptionConfigMapper;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
/**
* 充值优惠券修改 服务层实现。
*
* @author zs
* @since 2025-10-22
*/
@Service
public class MkCouponRedemptionConfigServiceImpl extends ServiceImpl<MkCouponRedemptionConfigMapper, MkCouponRedemptionConfig> implements MkCouponRedemptionConfigService{
@Resource
private MkCouponRedemptionCodeService codeService;
@Resource
private MkEnableConfigService enableConfigService;
@Resource
private MkShopCouponRecordService shopCouponRecordService;
@DubboReference
private ShopInfoService shopInfoService;
@DubboReference
private ShopUserService shopUserService;
@Override
public MkCouponRedemptionConfigVO detail(Long mainShopId, Long id) {
MkCouponRedemptionConfig redemptionConfig = getOne(new QueryWrapper().eq(MkCouponRedemptionConfig::getMainShopId, mainShopId).eq(MkCouponRedemptionConfig::getId, id));
if (redemptionConfig == null) {
return null;
}
MkCouponRedemptionConfigVO infoList = BeanUtil.copyProperties(redemptionConfig, MkCouponRedemptionConfigVO.class, "couponInfoList");
if (StrUtil.isNotBlank(redemptionConfig.getCouponInfoList())) {
infoList.setCouponInfoList(JSONArray.parseArray(redemptionConfig.getCouponInfoList(), CouponInfoDTO.class));
}
return infoList;
}
@Override
public Page<MkCouponRedemptionConfigVO> pageInfo(Long mainShopId, Integer status) {
QueryWrapper queryWrapper = new QueryWrapper().eq(MkCouponRedemptionConfig::getMainShopId, mainShopId)
.orderBy(MkCouponRedemptionConfig::getId, false);
switch (status) {
case 0:
queryWrapper.le(MkCouponRedemptionConfig::getStartTime, DateUtil.date()).ge(MkCouponRedemptionConfig::getEndTime, DateUtil.date());
break;
case 1:
queryWrapper.gt(MkCouponRedemptionConfig::getStartTime, DateUtil.date()).lt(MkCouponRedemptionConfig::getEndTime, DateUtil.date());
break;
}
Page<MkCouponRedemptionConfig> page = page(PageUtil.buildPage(), queryWrapper);
ArrayList<MkCouponRedemptionConfigVO> configList = new ArrayList<>();
page.getRecords().forEach(item -> {
if (item.getStartTime() != null && item.getEndTime() != null) {
item.setStatus(!item.getStartTime().isAfter(DateUtil.date().toLocalDateTime()) && item.getEndTime().isBefore(DateUtil.date().toLocalDateTime()) ? 0 : 1);
}else {
item.setStatus(0);
}
MkCouponRedemptionConfigVO config = BeanUtil.copyProperties(item, MkCouponRedemptionConfigVO.class, "couponInfoList");
if (StrUtil.isNotBlank(item.getCouponInfoList())) {
config.setCouponInfoList(JSONArray.parseArray(item.getCouponInfoList(), CouponInfoDTO.class));
config.setCouponNum(config.getCouponInfoList().stream().map(CouponInfoDTO::getNum).reduce(0, Integer::sum));
}
configList.add(config);
});
Page<MkCouponRedemptionConfigVO> page2 = new Page<>();
BeanUtil.copyProperties(page, page2, "records");
page2.setRecords(configList);
return page2;
}
@Override
public boolean add(Long mainShopId, MkCouponRedemptionConfigDTO dto) {
long count = count(new QueryWrapper().eq(MkCouponRedemptionConfig::getName, dto.getName()).eq(MkCouponRedemptionConfig::getMainShopId, mainShopId));
AssertUtil.isTrue(count > 0, "名称已存在");
MkCouponRedemptionConfig config = BeanUtil.copyProperties(dto, MkCouponRedemptionConfig.class, "couponInfoList");
config.setMainShopId(mainShopId);
config.setStock(config.getTotal());
if (dto.getCouponInfoList() != null && !dto.getCouponInfoList().isEmpty()) {
config.setCouponInfoList(JSONArray.toJSONString(dto.getCouponInfoList()));
}
save(config);
ArrayList<MkCouponRedemptionCode> codeArrayList = new ArrayList<>();
MkRechargeRedemptionConfigServiceImpl.generateCodes(config.getId(), config.getTotal()).forEach(code -> {
codeArrayList.add(new MkCouponRedemptionCode().setRedemptionId(config.getId())
.setMainShopId(mainShopId).setCode(code));
});
return codeService.saveBatch(codeArrayList);
}
@Override
public Boolean edit(Long shopId, MkCouponRedemptionConfigDTO dto) {
MkCouponRedemptionConfig config = getOne(new QueryWrapper().eq(MkCouponRedemptionConfig::getMainShopId, shopId).eq(MkCouponRedemptionConfig::getId, dto.getId()));
AssertUtil.isNull(config, "活动不存在");
if (dto.getStock() != null) {
if (config.getStock() < dto.getStock()) {
throw new CzgException("库存仅允许删减");
}
int subStock = config.getStock() - dto.getStock();
List<MkCouponRedemptionCode> subCodeList = codeService.list(new QueryWrapper().eq(MkCouponRedemptionCode::getRedemptionId, config.getId()).eq(MkCouponRedemptionCode::getStatus, 0).limit(subStock));
subCodeList.forEach(item -> item.setStatus(1));
codeService.updateBatch(subCodeList);
}
BeanUtil.copyProperties(dto, config, "total", "amount", "startTime", "endTime", "couponInfoList");
if (dto.getCouponInfoList() != null && !dto.getCouponInfoList().isEmpty()) {
config.setCouponInfoList(JSONArray.toJSONString(dto.getCouponInfoList()));
}
return updateById(config);
}
@Override
public Page<MkCouponRedemptionCodeVO> codeList(Long mainShopId, Long id, String code, Integer status) {
QueryWrapper queryWrapper = new MyQueryWrapper()
.selectAll(MkCouponRedemptionCode.class)
.select(ShopUser::getNickName, ShopUser::getPhone)
.eq(MkCouponRedemptionCode::getMainShopId, mainShopId)
.eq(MkCouponRedemptionCode::getRedemptionId, id)
.orderBy(MkCouponRedemptionCode::getId, false);
queryWrapper.eq(MkCouponRedemptionCode::getStatus, status);
if (StrUtil.isNotBlank(code)) {
queryWrapper.like(MkCouponRedemptionCode::getCode, code);
}
queryWrapper.leftJoin(ShopUser.class).on(ShopUser::getId, MkCouponRedemptionCode::getShopUserId);
return codeService.pageAs(PageUtil.buildPage(), queryWrapper, MkCouponRedemptionCodeVO.class);
}
@Override
public void exportCodeList(Long mainShopId, Long redemptionId, String code, Integer status, HttpServletResponse response, HttpServletRequest request) {
QueryWrapper queryWrapper = new MyQueryWrapper()
.selectAll(MkCouponRedemptionCode.class)
.select(ShopUser::getNickName, ShopUser::getPhone)
.eq(MkCouponRedemptionCode::getMainShopId, mainShopId)
.eq(MkCouponRedemptionCode::getRedemptionId, redemptionId);
queryWrapper.eq(MkCouponRedemptionCode::getStatus, status);
if (StrUtil.isNotBlank(code)) {
queryWrapper.like(MkCouponRedemptionCode::getCode, code);
}
queryWrapper.leftJoin(ShopUser.class).on(ShopUser::getId, MkCouponRedemptionCode::getShopUserId);
List<MkCouponRedemptionCodeVO> MkCouponRedemptionCodeVOS = codeService.listAs(queryWrapper, MkCouponRedemptionCodeVO.class);
List<Map<String, Object>> list = MkCouponRedemptionCodeVOS.stream()
.map(item -> {
Map<String, Object> map = new HashMap<>();
map.put("code", item.getCode());
map.put("redemptionTime", item.getRedemptionTime());
map.put("userInfo", item.getShopUserId() == null ? "" : item.getNickName() + " " + item.getPhone());
return map;
})
.toList();
// 1. 创建 ExcelWriter
ExcelWriter writer = ExcelUtil.getWriter(true);
// 2. 自定义标题别名(可选)
// 3. 写入数据
// 4. 设置响应头,告诉浏览器下载文件
try (writer) {
writer.addHeaderAlias("code", "兑换码");
writer.addHeaderAlias("redemptionTime", "兑换时间");
writer.addHeaderAlias("userInfo", "用户信息");
writer.write(list, true);
response.setContentType("application/vnd.ms-excel;charset=utf-8");
String fileName;
fileName = URLEncoder.encode("兑换码", StandardCharsets.UTF_8);
response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
// 5. 输出到浏览器
writer.flush(response.getOutputStream(), true);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void exchange(long userId, MkRedemptionDTO dto) {
Long mainShopId = shopInfoService.getMainIdByShopId(dto.getShopId());
enableConfigService.checkEnable(mainShopId, dto.getShopId(), TableValueConstant.EnableConfig.Type.RECHARGE_REDEMPTION, true);
ShopUser shopUserInfo = shopUserService.getShopUserInfo(dto.getShopId(), userId);
MkCouponRedemptionCode redemptionCode = codeService.getOne(new QueryWrapper().eq(MkCouponRedemptionCode::getMainShopId, mainShopId).eq(MkCouponRedemptionCode::getCode, dto.getCode()));
AssertUtil.isNull(redemptionCode, "兑换码不存在");
AssertUtil.isTrue(redemptionCode.getStatus() != 0, "兑换码不存在");
MkCouponRedemptionConfigVO config = detail(mainShopId, redemptionCode.getId());
AssertUtil.isNull(config, "兑换配置不存在");
AssertUtil.isTrue(config.getStock() <= 0, "兑换码可兑换库存不足");
if (config.getStartTime() != null) {
AssertUtil.isTrue(config.getStartTime().isAfter(DateUtil.date().toLocalDateTime()), "兑换活动未开始");
}
if (config.getEndTime() != null) {
AssertUtil.isTrue(config.getEndTime().isBefore(DateUtil.date().toLocalDateTime()), "兑换活动已结束");
}
if (config.getCouponInfoList() != null && !config.getCouponInfoList().isEmpty()) {
config.getCouponInfoList().forEach(item -> {
MkShopCouponGiftDTO giftDTO = new MkShopCouponGiftDTO().setCouponId(item.getId())
.setShopId(mainShopId)
.setSourceId(redemptionCode.getId())
.setShopUserId(shopUserInfo.getId())
.setSource("兑换码兑换");
shopCouponRecordService.receiveCoupon(giftDTO, item.getNum(), false);
});
}
redemptionCode.setStatus(1);
redemptionCode.setUserId(shopUserInfo.getUserId());
redemptionCode.setShopUserId(shopUserInfo.getId());
redemptionCode.setRedemptionTime(DateUtil.date().toLocalDateTime());
codeService.updateById(redemptionCode);
boolean update = updateChain().eq(MkRechargeRedemptionConfig::getId, config.getId()).setRaw(MkRechargeRedemptionConfig::getStock, "stock - 1")
.where("stock - 1 >= 0").update();
AssertUtil.isTrue(!update, "库存不足");
}
}

View File

@@ -1,18 +0,0 @@
package com.czg.service.market.service.impl;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.czg.market.entity.MkRechargeRedemptionCode;
import com.czg.market.service.MkRechargeRedemptionCodeService;
import com.czg.service.market.mapper.MkRechargeRedemptionCodeMapper;
import org.springframework.stereotype.Service;
/**
* 兑换码明细 服务层实现。
*
* @author zs
* @since 2025-10-21
*/
@Service
public class MkRechargeRedemptionCodeServiceImpl extends ServiceImpl<MkRechargeRedemptionCodeMapper, MkRechargeRedemptionCode> implements MkRechargeRedemptionCodeService{
}

View File

@@ -6,30 +6,33 @@ import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelUtil; import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter; import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.fastjson2.JSONArray;
import com.czg.account.dto.shopuser.ShopUserMoneyEditDTO; import com.czg.account.dto.shopuser.ShopUserMoneyEditDTO;
import com.czg.account.entity.ShopUser; import com.czg.account.entity.ShopUser;
import com.czg.account.service.ShopInfoService; import com.czg.account.service.ShopInfoService;
import com.czg.account.service.ShopUserService; import com.czg.account.service.ShopUserService;
import com.czg.account.service.UserInfoService;
import com.czg.constant.TableValueConstant; import com.czg.constant.TableValueConstant;
import com.czg.enums.ShopUserFlowBizEnum; import com.czg.enums.ShopUserFlowBizEnum;
import com.czg.exception.CzgException; import com.czg.exception.CzgException;
import com.czg.market.dto.MkRechargeRedemptionConfigDTO; import com.czg.market.dto.CouponInfoDTO;
import com.czg.market.dto.MkRedemptionConfigDTO;
import com.czg.market.dto.MkRedemptionDTO; import com.czg.market.dto.MkRedemptionDTO;
import com.czg.market.entity.MkRechargeRedemptionCode; import com.czg.market.dto.MkShopCouponGiftDTO;
import com.czg.market.entity.MkRedemptionCode;
import com.czg.market.entity.MkRedemptionConfig;
import com.czg.market.service.MkRedemptionCodeService;
import com.czg.market.service.MkEnableConfigService; import com.czg.market.service.MkEnableConfigService;
import com.czg.market.service.MkRechargeRedemptionCodeService; import com.czg.market.service.MkShopCouponRecordService;
import com.czg.market.vo.MkRechargeRedemptionCodeVO; import com.czg.market.vo.MkRedemptionConfigVO;
import com.czg.market.vo.MkRechargeRedemptionConfigVO; import com.czg.market.vo.MkRedemptionCodeVO;
import com.czg.utils.AssertUtil; import com.czg.utils.AssertUtil;
import com.czg.utils.MyQueryWrapper; import com.czg.utils.MyQueryWrapper;
import com.czg.utils.PageUtil; import com.czg.utils.PageUtil;
import com.mybatisflex.core.paginate.Page; import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper; import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl; import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.czg.market.entity.MkRechargeRedemptionConfig; import com.czg.market.service.MkRedemptionConfigService;
import com.czg.market.service.MkRechargeRedemptionConfigService; import com.czg.service.market.mapper.MkCouponRedemptionConfigMapper;
import com.czg.service.market.mapper.MkRechargeRedemptionConfigMapper;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
@@ -45,21 +48,21 @@ import java.util.*;
* 充值优惠券修改 服务层实现 * 充值优惠券修改 服务层实现
* *
* @author zs * @author zs
* @since 2025-10-21 * @since 2025-10-22
*/ */
@Service @Service
public class MkRechargeRedemptionConfigServiceImpl extends ServiceImpl<MkRechargeRedemptionConfigMapper, MkRechargeRedemptionConfig> implements MkRechargeRedemptionConfigService{ public class MkRedemptionConfigServiceImpl extends ServiceImpl<MkCouponRedemptionConfigMapper, MkRedemptionConfig> implements MkRedemptionConfigService {
@Resource @Resource
private MkRechargeRedemptionCodeService codeService; private MkRedemptionCodeService codeService;
@Resource @Resource
private MkEnableConfigService enableConfigService; private MkEnableConfigService enableConfigService;
@Resource
private MkShopCouponRecordService shopCouponRecordService;
@DubboReference @DubboReference
private ShopInfoService shopInfoService; private ShopInfoService shopInfoService;
@DubboReference @DubboReference
private ShopUserService shopUserService; private ShopUserService shopUserService;
/** /**
* 生成指定活动的兑换码集合 * 生成指定活动的兑换码集合
* @param activityId 活动ID * @param activityId 活动ID
@@ -117,53 +120,76 @@ public class MkRechargeRedemptionConfigServiceImpl extends ServiceImpl<MkRecharg
} }
} }
public static void main(String[] args) {
Set<String> codes = generateCodes(12, 1000);
codes.forEach(System.out::println);
}
@Override @Override
public MkRechargeRedemptionConfigVO detail(Long mainShopId) { public MkRedemptionConfigVO detail(Long mainShopId, Long id) {
return getOneAs(new QueryWrapper().eq(MkRechargeRedemptionConfig::getMainShopId, mainShopId), MkRechargeRedemptionConfigVO.class); MkRedemptionConfig redemptionConfig = getOne(new QueryWrapper().eq(MkRedemptionConfig::getMainShopId, mainShopId).eq(MkRedemptionConfig::getId, id));
if (redemptionConfig == null) {
return null;
}
MkRedemptionConfigVO infoList = BeanUtil.copyProperties(redemptionConfig, MkRedemptionConfigVO.class, "couponInfoList");
if (StrUtil.isNotBlank(redemptionConfig.getCouponInfoList())) {
infoList.setCouponInfoList(JSONArray.parseArray(redemptionConfig.getCouponInfoList(), CouponInfoDTO.class));
}
return infoList;
} }
@Override @Override
public Page<MkRechargeRedemptionConfig> pageInfo(Long mainShopId, Integer status) { public Page<MkRedemptionConfigVO> pageInfo(Long mainShopId, Integer status, boolean isRecharge) {
QueryWrapper queryWrapper = new QueryWrapper().eq(MkRechargeRedemptionConfig::getMainShopId, mainShopId) QueryWrapper queryWrapper = new QueryWrapper().eq(MkRedemptionConfig::getMainShopId, mainShopId)
.orderBy(MkRechargeRedemptionConfig::getId, false); .eq(MkRedemptionConfig::getType, isRecharge ? 0 : 1)
.orderBy(MkRedemptionConfig::getId, false);
switch (status) { switch (status) {
case 0: case 0:
queryWrapper.le(MkRechargeRedemptionConfig::getStartTime, DateUtil.date()).ge(MkRechargeRedemptionConfig::getEndTime, DateUtil.date()); queryWrapper.le(MkRedemptionConfig::getStartTime, DateUtil.date()).ge(MkRedemptionConfig::getEndTime, DateUtil.date());
break; break;
case 1: case 1:
queryWrapper.gt(MkRechargeRedemptionConfig::getStartTime, DateUtil.date()).lt(MkRechargeRedemptionConfig::getEndTime, DateUtil.date()); queryWrapper.gt(MkRedemptionConfig::getStartTime, DateUtil.date()).lt(MkRedemptionConfig::getEndTime, DateUtil.date());
break; break;
} }
Page<MkRechargeRedemptionConfig> page = page(PageUtil.buildPage(), queryWrapper); Page<MkRedemptionConfig> page = page(PageUtil.buildPage(), queryWrapper);
ArrayList<MkRedemptionConfigVO> configList = new ArrayList<>();
page.getRecords().forEach(item -> { page.getRecords().forEach(item -> {
if (item.getStartTime() != null && item.getEndTime() != null) { if (item.getStartTime() != null && item.getEndTime() != null) {
item.setStatus(!item.getStartTime().isAfter(DateUtil.date().toLocalDateTime()) && item.getEndTime().isBefore(DateUtil.date().toLocalDateTime()) ? 0 : 1); item.setStatus(!item.getStartTime().isAfter(DateUtil.date().toLocalDateTime()) && item.getEndTime().isBefore(DateUtil.date().toLocalDateTime()) ? 0 : 1);
}else { }else {
item.setStatus(0); item.setStatus(0);
} }
MkRedemptionConfigVO config = BeanUtil.copyProperties(item, MkRedemptionConfigVO.class, "couponInfoList");
if (StrUtil.isNotBlank(item.getCouponInfoList())) {
config.setCouponInfoList(JSONArray.parseArray(item.getCouponInfoList(), CouponInfoDTO.class));
config.setCouponNum(config.getCouponInfoList().stream().map(CouponInfoDTO::getNum).reduce(0, Integer::sum));
}
configList.add(config);
}); });
return page; Page<MkRedemptionConfigVO> page2 = new Page<>();
BeanUtil.copyProperties(page, page2, "records");
page2.setRecords(configList);
return page2;
} }
@Override @Override
public boolean add(Long mainShopId, MkRechargeRedemptionConfigDTO dto) { public boolean add(Long mainShopId, MkRedemptionConfigDTO dto, boolean isRecharge) {
long count = count(new QueryWrapper().eq(MkRechargeRedemptionConfig::getName, dto.getName()).eq(MkRechargeRedemptionConfig::getMainShopId, mainShopId)); long count = count(new QueryWrapper().eq(MkRedemptionConfig::getName, dto.getName()).eq(MkRedemptionConfig::getMainShopId, mainShopId)
.eq(MkRedemptionConfig::getType, isRecharge ? 0 : 1));
AssertUtil.isTrue(count > 0, "名称已存在"); AssertUtil.isTrue(count > 0, "名称已存在");
MkRechargeRedemptionConfig config = BeanUtil.copyProperties(dto, MkRechargeRedemptionConfig.class); MkRedemptionConfig config = BeanUtil.copyProperties(dto, MkRedemptionConfig.class, "couponInfoList");
config.setMainShopId(mainShopId); config.setMainShopId(mainShopId);
config.setStock(config.getTotal()); config.setStock(config.getTotal());
config.setType(isRecharge ? 0 : 1);
if (dto.getCouponInfoList() != null && !dto.getCouponInfoList().isEmpty()) {
config.setCouponInfoList(JSONArray.toJSONString(dto.getCouponInfoList()));
}
save(config); save(config);
ArrayList<MkRechargeRedemptionCode> codeArrayList = new ArrayList<>(); ArrayList<MkRedemptionCode> codeArrayList = new ArrayList<>();
generateCodes(config.getId(), config.getTotal()).forEach(code -> { generateCodes(config.getId(), config.getTotal()).forEach(code -> {
codeArrayList.add(new MkRechargeRedemptionCode().setRedemptionId(config.getId()) codeArrayList.add(new MkRedemptionCode().setRedemptionId(config.getId())
.setMainShopId(mainShopId).setCode(code)); .setMainShopId(mainShopId).setCode(code));
}); });
@@ -171,54 +197,59 @@ public class MkRechargeRedemptionConfigServiceImpl extends ServiceImpl<MkRecharg
} }
@Override @Override
public Boolean edit(Long shopId, MkRechargeRedemptionConfigDTO dto) { public Boolean edit(Long shopId, MkRedemptionConfigDTO dto, boolean isRecharge) {
MkRechargeRedemptionConfig config = getOne(new QueryWrapper().eq(MkRechargeRedemptionConfig::getMainShopId, shopId).eq(MkRechargeRedemptionConfig::getId, dto.getId())); MkRedemptionConfig config = getOne(new QueryWrapper().eq(MkRedemptionConfig::getMainShopId, shopId).eq(MkRedemptionConfig::getId, dto.getId())
.eq(MkRedemptionConfig::getType, isRecharge ? 0 : 1));
AssertUtil.isNull(config, "活动不存在"); AssertUtil.isNull(config, "活动不存在");
if (dto.getStock() != null) { if (dto.getStock() != null) {
if (config.getStock() < dto.getStock()) { if (config.getStock() < dto.getStock()) {
throw new CzgException("库存仅允许删减"); throw new CzgException("库存仅允许删减");
} }
int subStock = config.getStock() - dto.getStock(); int subStock = config.getStock() - dto.getStock();
List<MkRechargeRedemptionCode> subCodeList = codeService.list(new QueryWrapper().eq(MkRechargeRedemptionCode::getRedemptionId, config.getId()).eq(MkRechargeRedemptionCode::getStatus, 0).limit(subStock)); List<MkRedemptionCode> subCodeList = codeService.list(new QueryWrapper().eq(MkRedemptionCode::getRedemptionId, config.getId()).eq(MkRedemptionCode::getStatus, 0).limit(subStock));
subCodeList.forEach(item -> item.setStatus(1)); subCodeList.forEach(item -> item.setStatus(1));
codeService.updateBatch(subCodeList); codeService.updateBatch(subCodeList);
} }
BeanUtil.copyProperties(dto, config, "total", "amount", "startTime", "endTime"); BeanUtil.copyProperties(dto, config, "total", "amount", "startTime", "endTime", "couponInfoList");
if (dto.getCouponInfoList() != null && !dto.getCouponInfoList().isEmpty()) {
config.setCouponInfoList(JSONArray.toJSONString(dto.getCouponInfoList()));
}
return updateById(config); return updateById(config);
} }
@Override @Override
public Page<MkRechargeRedemptionCodeVO> codeList(Long mainShopId, Long id, String code, Integer status) { public Page<MkRedemptionCodeVO> codeList(Long mainShopId, Long id, String code, Integer status, boolean isRecharge) {
QueryWrapper queryWrapper = new MyQueryWrapper() QueryWrapper queryWrapper = new MyQueryWrapper()
.selectAll(MkRechargeRedemptionCode.class) .selectAll(MkRedemptionCode.class)
.select(ShopUser::getNickName, ShopUser::getPhone) .select(ShopUser::getNickName, ShopUser::getPhone)
.eq(MkRechargeRedemptionCode::getMainShopId, mainShopId) .eq(MkRedemptionCode::getMainShopId, mainShopId)
.eq(MkRechargeRedemptionCode::getRedemptionId, id) .eq(MkRedemptionCode::getRedemptionId, id)
.orderBy(MkRechargeRedemptionCode::getId, false); .orderBy(MkRedemptionCode::getId, false);
queryWrapper.eq(MkRechargeRedemptionCode::getStatus, status); queryWrapper.eq(MkRedemptionCode::getStatus, status);
if (StrUtil.isNotBlank(code)) { if (StrUtil.isNotBlank(code)) {
queryWrapper.like(MkRechargeRedemptionCode::getCode, code); queryWrapper.like(MkRedemptionCode::getCode, code);
} }
queryWrapper.leftJoin(ShopUser.class).on(ShopUser::getId, MkRechargeRedemptionCode::getShopUserId); queryWrapper.leftJoin(ShopUser.class).on(ShopUser::getId, MkRedemptionCode::getShopUserId);
return codeService.pageAs(PageUtil.buildPage(), queryWrapper, MkRechargeRedemptionCodeVO.class); return codeService.pageAs(PageUtil.buildPage(), queryWrapper, MkRedemptionCodeVO.class);
} }
@Override @Override
public void exportCodeList(Long mainShopId, Long redemptionId, String code, Integer status, HttpServletResponse response, HttpServletRequest request) { public void exportCodeList(Long mainShopId, Long redemptionId, String code, Integer status, HttpServletResponse response, HttpServletRequest request, boolean isRecharge) {
QueryWrapper queryWrapper = new MyQueryWrapper() QueryWrapper queryWrapper = new MyQueryWrapper()
.selectAll(MkRechargeRedemptionCode.class) .selectAll(MkRedemptionCode.class)
.select(ShopUser::getNickName, ShopUser::getPhone) .select(ShopUser::getNickName, ShopUser::getPhone)
.eq(MkRechargeRedemptionCode::getMainShopId, mainShopId) .eq(MkRedemptionCode::getMainShopId, mainShopId)
.eq(MkRechargeRedemptionCode::getRedemptionId, redemptionId); .eq(MkRedemptionCode::getRedemptionId, redemptionId);
queryWrapper.eq(MkRechargeRedemptionCode::getStatus, status); queryWrapper.eq(MkRedemptionCode::getStatus, status);
if (StrUtil.isNotBlank(code)) { if (StrUtil.isNotBlank(code)) {
queryWrapper.like(MkRechargeRedemptionCode::getCode, code); queryWrapper.like(MkRedemptionCode::getCode, code);
} }
queryWrapper.leftJoin(ShopUser.class).on(ShopUser::getId, MkRechargeRedemptionCode::getShopUserId); queryWrapper.leftJoin(ShopUser.class).on(ShopUser::getId, MkRedemptionCode::getShopUserId);
List<MkRechargeRedemptionCodeVO> mkRechargeRedemptionCodeVOS = codeService.listAs(queryWrapper, MkRechargeRedemptionCodeVO.class); List<MkRedemptionCodeVO> MkCouponRedemptionCodeVOS = codeService.listAs(queryWrapper, MkRedemptionCodeVO.class);
List<Map<String, Object>> list = mkRechargeRedemptionCodeVOS.stream() List<Map<String, Object>> list = MkCouponRedemptionCodeVOS.stream()
.map(item -> { .map(item -> {
Map<String, Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>();
map.put("code", item.getCode()); map.put("code", item.getCode());
@@ -247,9 +278,8 @@ public class MkRechargeRedemptionConfigServiceImpl extends ServiceImpl<MkRecharg
// 5. 输出到浏览器 // 5. 输出到浏览器
writer.flush(response.getOutputStream(), true); writer.flush(response.getOutputStream(), true);
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
@Override @Override
@@ -259,11 +289,11 @@ public class MkRechargeRedemptionConfigServiceImpl extends ServiceImpl<MkRecharg
enableConfigService.checkEnable(mainShopId, dto.getShopId(), TableValueConstant.EnableConfig.Type.RECHARGE_REDEMPTION, true); enableConfigService.checkEnable(mainShopId, dto.getShopId(), TableValueConstant.EnableConfig.Type.RECHARGE_REDEMPTION, true);
ShopUser shopUserInfo = shopUserService.getShopUserInfo(dto.getShopId(), userId); ShopUser shopUserInfo = shopUserService.getShopUserInfo(dto.getShopId(), userId);
MkRechargeRedemptionCode redemptionCode = codeService.getOne(new QueryWrapper().eq(MkRechargeRedemptionCode::getMainShopId, mainShopId).eq(MkRechargeRedemptionCode::getCode, dto.getCode())); MkRedemptionCode redemptionCode = codeService.getOne(new QueryWrapper().eq(MkRedemptionCode::getMainShopId, mainShopId).eq(MkRedemptionCode::getCode, dto.getCode()));
AssertUtil.isNull(redemptionCode, "兑换码不存在"); AssertUtil.isNull(redemptionCode, "兑换码不存在");
AssertUtil.isTrue(redemptionCode.getStatus() != 0, "兑换码不存在"); AssertUtil.isTrue(redemptionCode.getStatus() != 0, "兑换码不存在");
MkRechargeRedemptionConfig config = getOne(new QueryWrapper().eq(MkRechargeRedemptionConfig::getId, redemptionCode.getRedemptionId()).eq(MkRechargeRedemptionConfig::getMainShopId, mainShopId)); MkRedemptionConfigVO config = detail(mainShopId, redemptionCode.getId());
AssertUtil.isNull(config, "兑换配置不存在"); AssertUtil.isNull(config, "兑换配置不存在");
AssertUtil.isTrue(config.getStock() <= 0, "兑换码可兑换库存不足"); AssertUtil.isTrue(config.getStock() <= 0, "兑换码可兑换库存不足");
if (config.getStartTime() != null) { if (config.getStartTime() != null) {
@@ -273,21 +303,37 @@ public class MkRechargeRedemptionConfigServiceImpl extends ServiceImpl<MkRecharg
AssertUtil.isTrue(config.getEndTime().isBefore(DateUtil.date().toLocalDateTime()), "兑换活动已结束"); AssertUtil.isTrue(config.getEndTime().isBefore(DateUtil.date().toLocalDateTime()), "兑换活动已结束");
} }
ShopUserMoneyEditDTO shopUserMoneyEditDTO = new ShopUserMoneyEditDTO() if (config.getType() == 0) {
.setId(shopUserInfo.getId()) ShopUserMoneyEditDTO shopUserMoneyEditDTO = new ShopUserMoneyEditDTO()
.setMoney(config.getAmount()) .setId(shopUserInfo.getId())
.setType(1) .setMoney(config.getAmount())
.setBizEnum(ShopUserFlowBizEnum.RECHARGE_REDEMPTION) .setType(1)
.setRelationId(redemptionCode.getId()); .setBizEnum(ShopUserFlowBizEnum.RECHARGE_REDEMPTION)
.setRelationId(redemptionCode.getId());
shopUserService.updateMoney(shopUserMoneyEditDTO); shopUserService.updateMoney(shopUserMoneyEditDTO);
redemptionCode.setStatus(1); }else {
redemptionCode.setUserId(shopUserInfo.getUserId()); if (config.getCouponInfoList() != null && !config.getCouponInfoList().isEmpty()) {
redemptionCode.setShopUserId(shopUserInfo.getId()); config.getCouponInfoList().forEach(item -> {
redemptionCode.setRedemptionTime(DateUtil.date().toLocalDateTime()); MkShopCouponGiftDTO giftDTO = new MkShopCouponGiftDTO().setCouponId(item.getId())
codeService.updateById(redemptionCode); .setShopId(mainShopId)
.setSourceId(redemptionCode.getId())
.setShopUserId(shopUserInfo.getId())
.setSource("兑换码兑换");
shopCouponRecordService.receiveCoupon(giftDTO, item.getNum(), false);
boolean update = updateChain().eq(MkRechargeRedemptionConfig::getId, config.getId()).setRaw(MkRechargeRedemptionConfig::getStock, "stock - 1") });
}
}
redemptionCode.setStatus(1);
redemptionCode.setUserId(shopUserInfo.getUserId());
redemptionCode.setShopUserId(shopUserInfo.getId());
redemptionCode.setRedemptionTime(DateUtil.date().toLocalDateTime());
codeService.updateById(redemptionCode);
boolean update = updateChain().eq(MkRedemptionConfig::getId, config.getId()).setRaw(MkRedemptionConfig::getStock, "stock - 1")
.where("stock - 1 >= 0").update(); .where("stock - 1 >= 0").update();
AssertUtil.isTrue(!update, "库存不足"); AssertUtil.isTrue(!update, "库存不足");

View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.czg.service.market.mapper.MkRechargeRedemptionCodeMapper">
</mapper>

View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.czg.service.market.mapper.MkRechargeRedemptionConfigMapper">
</mapper>