refactor(entity): 重构实体类并优化券码生成逻辑

- 移除 BaseEntity 类,将通用字段直接集成到各实体类中
- 更新实体类字段名称,如 createdTime 改为 createTime- 在 PriceVoucherCode 实体中添加生成安全券码的逻辑
- 更新相关服务类中的方法调用,以适应新的字段名称
This commit is contained in:
2025-08-21 14:37:55 +08:00
parent b4b542046f
commit 3d49c47006
12 changed files with 213 additions and 78 deletions

View File

@@ -1,29 +0,0 @@
package com.ycwl.basic.pricing.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.util.Date;
/**
* 基础实体类
*/
@Data
public class BaseEntity {
@TableId(type = IdType.AUTO)
private Long id;
private Date createdTime;
private Date updatedTime;
private Long createBy;
private Long updateBy;
private Integer deleted;
private Date deletedAt;
}

View File

@@ -1,23 +1,27 @@
package com.ycwl.basic.pricing.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.ycwl.basic.pricing.dto.BundleProductItem;
import com.ycwl.basic.pricing.handler.BundleProductListTypeHandler;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.ibatis.type.JdbcType;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* 一口价配置实体
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("price_bundle_config")
public class PriceBundleConfig extends BaseEntity {
public class PriceBundleConfig {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 套餐名称
@@ -55,4 +59,18 @@ public class PriceBundleConfig extends BaseEntity {
* 是否启用
*/
private Boolean isActive;
@TableField("create_time")
private Date createTime;
@TableField("update_time")
private Date updateTime;
private Long createBy;
private Long updateBy;
private Integer deleted;
private Date deletedAt;
}

View File

@@ -1,9 +1,11 @@
package com.ycwl.basic.pricing.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.ycwl.basic.pricing.enums.CouponStatus;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
@@ -11,9 +13,11 @@ import java.util.Date;
* 优惠券领用记录实体
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("price_coupon_claim_record")
public class PriceCouponClaimRecord extends BaseEntity {
public class PriceCouponClaimRecord {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 优惠券ID
@@ -49,4 +53,14 @@ public class PriceCouponClaimRecord extends BaseEntity {
* 景区ID - 记录优惠券在哪个景区被领取/使用
*/
private String scenicId;
@TableField("create_time")
private Date createTime;
@TableField("update_time")
private Date updateTime;
private Integer deleted;
private Date deletedAt;
}

View File

@@ -1,20 +1,25 @@
package com.ycwl.basic.pricing.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.ycwl.basic.pricing.enums.CouponType;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
/**
* 优惠券配置实体
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("price_coupon_config")
public class PriceCouponConfig extends BaseEntity {
public class PriceCouponConfig {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 优惠券名称
@@ -75,4 +80,18 @@ public class PriceCouponConfig extends BaseEntity {
* 景区ID - 限制优惠券只能在该景区使用
*/
private String scenicId;
@TableField("create_time")
private Date createTime;
@TableField("update_time")
private Date updateTime;
private Long createBy;
private Long updateBy;
private Integer deleted;
private Date deletedAt;
}

View File

@@ -1,18 +1,23 @@
package com.ycwl.basic.pricing.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.util.Date;
/**
* 商品价格配置实体
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("price_product_config")
public class PriceProductConfig extends BaseEntity {
public class PriceProductConfig {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 商品类型
@@ -53,4 +58,18 @@ public class PriceProductConfig extends BaseEntity {
* 是否启用
*/
private Boolean isActive;
@TableField("create_time")
private Date createTime;
@TableField("update_time")
private Date updateTime;
private Long createBy;
private Long updateBy;
private Integer deleted;
private Date deletedAt;
}

View File

@@ -1,18 +1,23 @@
package com.ycwl.basic.pricing.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.util.Date;
/**
* 阶梯定价配置实体
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("price_tier_config")
public class PriceTierConfig extends BaseEntity {
public class PriceTierConfig {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 商品类型
@@ -63,4 +68,18 @@ public class PriceTierConfig extends BaseEntity {
* 是否启用
*/
private Boolean isActive;
@TableField("create_time")
private Date createTime;
@TableField("update_time")
private Date updateTime;
private Long createBy;
private Long updateBy;
private Integer deleted;
private Date deletedAt;
}

View File

@@ -1,10 +1,10 @@
package com.ycwl.basic.pricing.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.util.Date;
@@ -13,9 +13,8 @@ import java.util.Date;
* 券码批次配置实体
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("price_voucher_batch_config")
public class PriceVoucherBatchConfig extends BaseEntity {
public class PriceVoucherBatchConfig {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@@ -65,8 +64,17 @@ public class PriceVoucherBatchConfig extends BaseEntity {
*/
private Integer status;
/**
* 创建人ID
*/
@TableField("create_time")
private Date createTime;
@TableField("update_time")
private Date updateTime;
private Long createBy;
private Long updateBy;
private Integer deleted;
private Date deletedAt;
}

View File

@@ -1,10 +1,10 @@
package com.ycwl.basic.pricing.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
@@ -12,9 +12,8 @@ import java.util.Date;
* 券码实体
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("price_voucher_code")
public class PriceVoucherCode extends BaseEntity {
public class PriceVoucherCode {
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@@ -58,4 +57,14 @@ public class PriceVoucherCode extends BaseEntity {
* 使用备注
*/
private String remark;
@TableField("create_time")
private Date createTime;
@TableField("update_time")
private Date updateTime;
private Integer deleted;
private Date deletedAt;
}

View File

@@ -152,7 +152,7 @@ public class CouponServiceImpl implements ICouponService {
record.setStatus(CouponStatus.USED);
record.setUseTime(useTime);
record.setOrderId(request.getOrderId());
record.setUpdatedTime(new Date());
record.setUpdateTime(new Date());
// 如果请求中包含景区ID,记录到使用记录中
if (request.getScenicId() != null && !request.getScenicId().isEmpty()) {

View File

@@ -35,8 +35,8 @@ public class PricingManagementServiceImpl implements IPricingManagementService {
}
}
config.setCreatedTime(new Date());
config.setUpdatedTime(new Date());
config.setCreateTime(new Date());
config.setUpdateTime(new Date());
productConfigMapper.insertProductConfig(config);
return config.getId();
}
@@ -44,7 +44,7 @@ public class PricingManagementServiceImpl implements IPricingManagementService {
@Override
@Transactional
public boolean updateProductConfig(PriceProductConfig config) {
config.setUpdatedTime(new Date());
config.setUpdateTime(new Date());
return productConfigMapper.updateProductConfig(config) > 0;
}
@@ -58,8 +58,8 @@ public class PricingManagementServiceImpl implements IPricingManagementService {
config.getProductType(), config.getMinQuantity(), config.getMaxQuantity());
}
config.setCreatedTime(new Date());
config.setUpdatedTime(new Date());
config.setCreateTime(new Date());
config.setUpdateTime(new Date());
tierConfigMapper.insertTierConfig(config);
return config.getId();
}
@@ -67,15 +67,15 @@ public class PricingManagementServiceImpl implements IPricingManagementService {
@Override
@Transactional
public boolean updateTierConfig(PriceTierConfig config) {
config.setUpdatedTime(new Date());
config.setUpdateTime(new Date());
return tierConfigMapper.updateTierConfig(config) > 0;
}
@Override
@Transactional
public Long createCouponConfig(PriceCouponConfig config) {
config.setCreatedTime(new Date());
config.setUpdatedTime(new Date());
config.setCreateTime(new Date());
config.setUpdateTime(new Date());
couponConfigMapper.insertCoupon(config);
return config.getId();
}
@@ -83,7 +83,7 @@ public class PricingManagementServiceImpl implements IPricingManagementService {
@Override
@Transactional
public boolean updateCouponConfig(PriceCouponConfig config) {
config.setUpdatedTime(new Date());
config.setUpdateTime(new Date());
return couponConfigMapper.updateCoupon(config) > 0;
}
@@ -91,8 +91,8 @@ public class PricingManagementServiceImpl implements IPricingManagementService {
@Transactional
public Long createCouponClaimRecord(PriceCouponClaimRecord record) {
record.setClaimTime(new Date());
record.setCreatedTime(new Date());
record.setUpdatedTime(new Date());
record.setCreateTime(new Date());
record.setUpdateTime(new Date());
couponClaimRecordMapper.insertClaimRecord(record);
return record.getId();
}
@@ -100,15 +100,15 @@ public class PricingManagementServiceImpl implements IPricingManagementService {
@Override
@Transactional
public boolean updateCouponClaimRecord(PriceCouponClaimRecord record) {
record.setUpdatedTime(new Date());
record.setUpdateTime(new Date());
return couponClaimRecordMapper.updateClaimRecord(record) > 0;
}
@Override
@Transactional
public Long createBundleConfig(PriceBundleConfig config) {
config.setCreatedTime(new Date());
config.setUpdatedTime(new Date());
config.setCreateTime(new Date());
config.setUpdateTime(new Date());
bundleConfigMapper.insertBundleConfig(config);
return config.getId();
}
@@ -116,7 +116,7 @@ public class PricingManagementServiceImpl implements IPricingManagementService {
@Override
@Transactional
public boolean updateBundleConfig(PriceBundleConfig config) {
config.setUpdatedTime(new Date());
config.setUpdateTime(new Date());
return bundleConfigMapper.updateBundleConfig(config) > 0;
}

View File

@@ -64,7 +64,7 @@ public class VoucherBatchServiceImpl implements VoucherBatchService {
batch.setUsedCount(0);
batch.setClaimedCount(0);
batch.setStatus(1);
batch.setCreatedTime(new Date());
batch.setCreateTime(new Date());
String userIdStr = BaseContextHandler.getUserId();
if (userIdStr != null) {
batch.setCreateBy(Long.valueOf(userIdStr));
@@ -88,7 +88,7 @@ public class VoucherBatchServiceImpl implements VoucherBatchService {
.eq(req.getBrokerId() != null, PriceVoucherBatchConfig::getBrokerId, req.getBrokerId())
.eq(req.getStatus() != null, PriceVoucherBatchConfig::getStatus, req.getStatus())
.like(StringUtils.hasText(req.getBatchName()), PriceVoucherBatchConfig::getBatchName, req.getBatchName())
.orderByDesc(PriceVoucherBatchConfig::getCreatedTime);
.orderByDesc(PriceVoucherBatchConfig::getCreateTime);
Page<PriceVoucherBatchConfig> entityPage = voucherBatchMapper.selectPage(page, wrapper);
@@ -174,7 +174,7 @@ public class VoucherBatchServiceImpl implements VoucherBatchService {
.eq(PriceVoucherBatchConfig::getStatus, 1)
.eq(PriceVoucherBatchConfig::getDeleted, 0)
.apply("claimed_count < total_count")
.orderByDesc(PriceVoucherBatchConfig::getCreatedTime);
.orderByDesc(PriceVoucherBatchConfig::getCreateTime);
return voucherBatchMapper.selectOne(wrapper);
}

View File

@@ -15,6 +15,7 @@ import com.ycwl.basic.pricing.mapper.PriceVoucherCodeMapper;
import com.ycwl.basic.pricing.service.VoucherBatchService;
import com.ycwl.basic.pricing.service.VoucherCodeService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
@@ -22,14 +23,23 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.Objects;
@Slf4j
@Service
public class VoucherCodeServiceImpl implements VoucherCodeService {
// 券码生成相关常量
private static final String SAFE_CHARS = "23456789ABCDEFGHJKMNPQRTUVWXYZ";
private static final char[] SAFE_CHARS_ARRAY = SAFE_CHARS.toCharArray();
private static final int CODE_LENGTH = 6;
private static final int MAX_RETRY = 10;
private static final SecureRandom RANDOM = new SecureRandom();
@Autowired
private PriceVoucherCodeMapper voucherCodeMapper;
@Autowired
@@ -48,7 +58,7 @@ public class VoucherCodeServiceImpl implements VoucherCodeService {
code.setScenicId(scenicId);
code.setCode(generateVoucherCode());
code.setStatus(VoucherCodeStatus.UNCLAIMED.getCode());
code.setCreatedTime(new Date());
code.setCreateTime(new Date());
code.setDeleted(0);
codes.add(code);
}
@@ -107,7 +117,7 @@ public class VoucherCodeServiceImpl implements VoucherCodeService {
.eq(req.getFaceId() != null, PriceVoucherCode::getFaceId, req.getFaceId())
.eq(req.getStatus() != null, PriceVoucherCode::getStatus, req.getStatus())
.like(StringUtils.hasText(req.getCode()), PriceVoucherCode::getCode, req.getCode())
.orderByDesc(PriceVoucherCode::getCreatedTime);
.orderByDesc(PriceVoucherCode::getId);
Page<PriceVoucherCode> entityPage = voucherCodeMapper.selectPage(page, wrapper);
@@ -150,7 +160,7 @@ public class VoucherCodeServiceImpl implements VoucherCodeService {
throw new BizException(404, "券码不存在");
}
if (code.getStatus() != VoucherCodeStatus.CLAIMED_UNUSED.getCode()) {
if (!Objects.equals(code.getStatus(), VoucherCodeStatus.CLAIMED_UNUSED.getCode())) {
throw new BizException(400, "券码状态异常,无法使用");
}
@@ -169,8 +179,56 @@ public class VoucherCodeServiceImpl implements VoucherCodeService {
return count == 0;
}
/**
* 生成6位安全券码(去除易混淆字符)
* 字符集:数字2-9 + 大写字母(去除0,1,I,L,O,S)
*
* @return 6位券码
*/
private String generateVoucherCode() {
return UUID.randomUUID().toString().replace("-", "").substring(0, 8).toUpperCase();
for (int attempt = 0; attempt < MAX_RETRY; attempt++) {
String code = generateRandomCode();
log.debug("生成券码候选: {} (尝试第{}次)", code, attempt + 1);
if (!isCodeExists(code)) {
log.info("成功生成券码: {} (字符集大小: {}, 理论组合数: {})",
code, SAFE_CHARS.length(), Math.pow(SAFE_CHARS.length(), CODE_LENGTH));
return code;
}
log.warn("券码重复,重新生成: {}", code);
}
// 如果重试次数用完仍有重复,抛出异常
log.error("券码生成失败:达到最大重试次数 {}", MAX_RETRY);
throw new RuntimeException("券码生成失败:达到最大重试次数,请稍后重试");
}
/**
* 生成随机6位字符
*
* @return 随机6位字符
*/
private String generateRandomCode() {
StringBuilder code = new StringBuilder(CODE_LENGTH);
for (int i = 0; i < CODE_LENGTH; i++) {
int randomIndex = RANDOM.nextInt(SAFE_CHARS_ARRAY.length);
code.append(SAFE_CHARS_ARRAY[randomIndex]);
}
return code.toString();
}
/**
* 检查券码是否已存在
*
* @param code 券码
* @return 是否存在
*/
private boolean isCodeExists(String code) {
LambdaQueryWrapper<PriceVoucherCode> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(PriceVoucherCode::getCode, code)
.eq(PriceVoucherCode::getDeleted, 0);
return voucherCodeMapper.selectCount(wrapper) > 0;
}
private VoucherCodeResp convertToResp(PriceVoucherCode code, PriceVoucherBatchConfig batch) {