|
@@ -13,6 +13,11 @@ import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
import javax.annotation.Resource;
|
|
|
import java.util.Date;
|
|
import java.util.Date;
|
|
|
|
|
+import com.etotem.cfc.service.CouponService;
|
|
|
|
|
+import com.etotem.cfc.service.SysConfigService;
|
|
|
|
|
+import com.etotem.cfc.mapper.FamilyPlatformExchangeRecordMapper;
|
|
|
|
|
+import com.etotem.cfc.entity.FamilyPlatformExchangeRecord;
|
|
|
|
|
+import java.util.Calendar;
|
|
|
import java.util.HashMap;
|
|
import java.util.HashMap;
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
import java.util.Map;
|
|
@@ -37,9 +42,18 @@ public class FamilyPlatformPointsService {
|
|
|
@Resource
|
|
@Resource
|
|
|
private FamilyPlatformBalanceLogMapper logMapper;
|
|
private FamilyPlatformBalanceLogMapper logMapper;
|
|
|
|
|
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private SysConfigService sysConfigService;
|
|
|
|
|
+
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private CouponService couponService;
|
|
|
|
|
+
|
|
|
@Resource
|
|
@Resource
|
|
|
private CouponMapper couponMapper;
|
|
private CouponMapper couponMapper;
|
|
|
|
|
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private FamilyPlatformExchangeRecordMapper exchangeRecordMapper;
|
|
|
|
|
+
|
|
|
/** 获取或创建家庭的积分池记录(悲观锁) */
|
|
/** 获取或创建家庭的积分池记录(悲观锁) */
|
|
|
@Transactional
|
|
@Transactional
|
|
|
public FamilyPlatformBalance getOrCreate(Long familyId) {
|
|
public FamilyPlatformBalance getOrCreate(Long familyId) {
|
|
@@ -191,22 +205,89 @@ public class FamilyPlatformPointsService {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
- * 用家庭CF值兑换优惠券(扣减家庭池,不扣个人积分)
|
|
|
|
|
|
|
+ * 用家庭CF值兑换优惠券:校验 → 扣家庭池 → 发券 → 落记录
|
|
|
*/
|
|
*/
|
|
|
@Transactional
|
|
@Transactional
|
|
|
public void exchangeCouponByCf(Long familyId, Long couponId, Long refUserId) {
|
|
public void exchangeCouponByCf(Long familyId, Long couponId, Long refUserId) {
|
|
|
|
|
+ // 1. 校验优惠券
|
|
|
Coupon coupon = couponMapper.selectById(couponId);
|
|
Coupon coupon = couponMapper.selectById(couponId);
|
|
|
if (coupon == null) {
|
|
if (coupon == null) {
|
|
|
throw new RuntimeException("优惠券不存在");
|
|
throw new RuntimeException("优惠券不存在");
|
|
|
}
|
|
}
|
|
|
Integer pointsPrice = coupon.getPointsPrice();
|
|
Integer pointsPrice = coupon.getPointsPrice();
|
|
|
if (pointsPrice == null || pointsPrice <= 0) {
|
|
if (pointsPrice == null || pointsPrice <= 0) {
|
|
|
- throw new RuntimeException("该优惠券不支持积分兑换");
|
|
|
|
|
|
|
+ throw new RuntimeException("该优惠券不支持CF值兑换");
|
|
|
|
|
+ }
|
|
|
|
|
+ Date now = new Date();
|
|
|
|
|
+ if (coupon.getValidFrom() != null && now.before(coupon.getValidFrom())) {
|
|
|
|
|
+ throw new RuntimeException("优惠券尚未开始");
|
|
|
}
|
|
}
|
|
|
- // 扣除家庭池CF值
|
|
|
|
|
|
|
+ if (coupon.getValidUntil() != null && now.after(coupon.getValidUntil())) {
|
|
|
|
|
+ throw new RuntimeException("优惠券已过期");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 家庭级日限次(cf_exchange_daily_limit,默认5)
|
|
|
|
|
+ int dailyLimit = 5;
|
|
|
|
|
+ try {
|
|
|
|
|
+ String limitStr = sysConfigService.getValue("cf_exchange_daily_limit");
|
|
|
|
|
+ if (limitStr != null && !limitStr.isEmpty()) dailyLimit = Integer.parseInt(limitStr);
|
|
|
|
|
+ } catch (Exception ignored) {}
|
|
|
|
|
+ Calendar cal = Calendar.getInstance();
|
|
|
|
|
+ cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0);
|
|
|
|
|
+ cal.set(Calendar.SECOND, 0); cal.set(Calendar.MILLISECOND, 0);
|
|
|
|
|
+ long todayCount = exchangeRecordMapper.selectCount(
|
|
|
|
|
+ new LambdaQueryWrapper<FamilyPlatformExchangeRecord>()
|
|
|
|
|
+ .eq(FamilyPlatformExchangeRecord::getFamilyId, familyId)
|
|
|
|
|
+ .eq(FamilyPlatformExchangeRecord::getStatus, "completed")
|
|
|
|
|
+ .ge(FamilyPlatformExchangeRecord::getCreatedAt, cal.getTime()));
|
|
|
|
|
+ if (todayCount >= dailyLimit) {
|
|
|
|
|
+ throw new RuntimeException("家庭今日CF值兑换次数已达上限(" + dailyLimit + "次)");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 单券模板日限次(cf_coupon_exchange_daily_limit,默认1)
|
|
|
|
|
+ int couponDailyLimit = 1;
|
|
|
|
|
+ try {
|
|
|
|
|
+ String cdlStr = sysConfigService.getValue("cf_coupon_exchange_daily_limit");
|
|
|
|
|
+ if (cdlStr != null && !cdlStr.isEmpty()) couponDailyLimit = Integer.parseInt(cdlStr);
|
|
|
|
|
+ } catch (Exception ignored) {}
|
|
|
|
|
+ long couponTodayCount = exchangeRecordMapper.selectCount(
|
|
|
|
|
+ new LambdaQueryWrapper<FamilyPlatformExchangeRecord>()
|
|
|
|
|
+ .eq(FamilyPlatformExchangeRecord::getFamilyId, familyId)
|
|
|
|
|
+ .eq(FamilyPlatformExchangeRecord::getCouponId, couponId)
|
|
|
|
|
+ .eq(FamilyPlatformExchangeRecord::getStatus, "completed")
|
|
|
|
|
+ .ge(FamilyPlatformExchangeRecord::getCreatedAt, cal.getTime()));
|
|
|
|
|
+ if (couponTodayCount >= couponDailyLimit) {
|
|
|
|
|
+ throw new RuntimeException("该优惠券今日兑换次数已达上限");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 扣减家庭池CF值
|
|
|
spend(familyId, pointsPrice, "coupon_exchange", couponId,
|
|
spend(familyId, pointsPrice, "coupon_exchange", couponId,
|
|
|
"兑换优惠券: " + (coupon.getName() != null ? coupon.getName() : "优惠券"));
|
|
"兑换优惠券: " + (coupon.getName() != null ? coupon.getName() : "优惠券"));
|
|
|
- // TODO: 实际发券逻辑(关联到 refUserId 的优惠券账户)
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 发券给操作用户
|
|
|
|
|
+ couponService.grant(refUserId, couponId, "CF_EXCHANGE", null, "family:" + familyId);
|
|
|
|
|
+
|
|
|
|
|
+ // 6. 落兑换记录
|
|
|
|
|
+ FamilyPlatformExchangeRecord record = new FamilyPlatformExchangeRecord();
|
|
|
|
|
+ record.setUserId(refUserId);
|
|
|
|
|
+ record.setFamilyId(familyId);
|
|
|
|
|
+ record.setCouponId(couponId);
|
|
|
|
|
+ record.setCouponName(coupon.getName());
|
|
|
|
|
+ record.setCfCost(pointsPrice);
|
|
|
|
|
+ record.setStatus("completed");
|
|
|
|
|
+ record.setRedeemCode(java.util.UUID.randomUUID().toString().replace("-", "").substring(0, 12).toUpperCase());
|
|
|
|
|
+ record.setCreatedAt(now);
|
|
|
|
|
+ record.setUpdatedAt(now);
|
|
|
|
|
+ exchangeRecordMapper.insert(record);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /** 查询家庭CF兑换记录分页 */
|
|
|
|
|
+ public Page<FamilyPlatformExchangeRecord> getExchangeRecords(Long familyId, Integer page, Integer size) {
|
|
|
|
|
+ Page<FamilyPlatformExchangeRecord> pageParam = new Page<>(page, size);
|
|
|
|
|
+ return exchangeRecordMapper.selectPage(pageParam,
|
|
|
|
|
+ new LambdaQueryWrapper<FamilyPlatformExchangeRecord>()
|
|
|
|
|
+ .eq(FamilyPlatformExchangeRecord::getFamilyId, familyId)
|
|
|
|
|
+ .orderByDesc(FamilyPlatformExchangeRecord::getCreatedAt));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/** 查询家庭 CF 值余额 */
|
|
/** 查询家庭 CF 值余额 */
|