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

@@ -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) {