|
|
@@ -788,7 +788,8 @@ public class MembershipService implements MembershipServiceInterface {
|
|
|
membership.setFamilyId(order.getFamilyId());
|
|
|
membership.setLevelCode(order.getLevelCode());
|
|
|
membership.setStartDate(new Date());
|
|
|
- membership.setEndDate(calculateEndDate(order.getPaymentType(), order.getPeriod()));
|
|
|
+ Date expireTime = calculateEndDate(order.getPaymentType(), order.getPeriod());
|
|
|
+ membership.setEndDate(expireTime);
|
|
|
membership.setPaymentMethod(payMethod);
|
|
|
membership.setPaymentStatus("paid");
|
|
|
membership.setOrderNo(order.getOrderNo());
|
|
|
@@ -796,24 +797,8 @@ public class MembershipService implements MembershipServiceInterface {
|
|
|
membership.setAmount(order.getAmount());
|
|
|
membershipMapper.insert(membership);
|
|
|
|
|
|
- // 升级用户等级
|
|
|
- String fromLevel = adminUser.getMemberLevel() != null ? adminUser.getMemberLevel() : "FREE";
|
|
|
- Date expireTime = new Date(System.currentTimeMillis() + 365L * 24 * 60 * 60 * 1000);
|
|
|
- adminUser.setMemberLevel(order.getLevelCode());
|
|
|
- adminUser.setMemberExpireTime(expireTime);
|
|
|
- adminUser.setUpdatedAt(new Date());
|
|
|
- userMapper.updateById(adminUser);
|
|
|
-
|
|
|
- // 创建升级记录
|
|
|
- MemberUpgradeRecord upgradeRecord = new MemberUpgradeRecord();
|
|
|
- upgradeRecord.setUserId(adminUserId);
|
|
|
- upgradeRecord.setFromLevel(fromLevel);
|
|
|
- upgradeRecord.setToLevel(order.getLevelCode());
|
|
|
- upgradeRecord.setUpgradeType("pay");
|
|
|
- upgradeRecord.setOrderId(order.getId());
|
|
|
- upgradeRecord.setExpireTime(expireTime);
|
|
|
- upgradeRecord.setCreatedAt(new Date());
|
|
|
- memberUpgradeRecordMapper.insert(upgradeRecord);
|
|
|
+ // 方案B:全家同步会员身份(使用 membership.getEndDate() 统一到期时间,修正原硬编码 365 天 bug)
|
|
|
+ syncMembershipToFamilyMembers(order.getFamilyId(), order.getLevelCode(), expireTime, "pay", order.getId());
|
|
|
|
|
|
// 发放JOIN会员券(按等级匹配grantType=JOIN的券模板)
|
|
|
try {
|
|
|
@@ -869,6 +854,128 @@ public class MembershipService implements MembershipServiceInterface {
|
|
|
return members.get(0).getId();
|
|
|
}
|
|
|
|
|
|
+ // ==================== 方案B:家庭会员全量同步辅助方法 ====================
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 方案B:获取家庭当前有效的付费会员记录(未过期、paymentStatus=paid)
|
|
|
+ * @return 有效会员记录,无则返回 null
|
|
|
+ */
|
|
|
+ private FamilyMembership getActiveFamilyMembership(Long familyId) {
|
|
|
+ if (familyId == null) return null;
|
|
|
+ return membershipMapper.selectOne(
|
|
|
+ new LambdaQueryWrapper<FamilyMembership>()
|
|
|
+ .eq(FamilyMembership::getFamilyId, familyId)
|
|
|
+ .eq(FamilyMembership::getPaymentStatus, "paid")
|
|
|
+ .gt(FamilyMembership::getEndDate, new Date())
|
|
|
+ .orderByDesc(FamilyMembership::getEndDate)
|
|
|
+ .last("LIMIT 1"));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 方案B:将会员身份同步给家庭所有成员(含不可登录成员,即 userId 非空的所有 users 记录)
|
|
|
+ * 用于:会员开通、赠送、试用开通、消费自动升级
|
|
|
+ * @param familyId 家庭ID
|
|
|
+ * @param levelCode 会员等级代码(FAMILY/PREMIUM/LIFETIME等)
|
|
|
+ * @param expireTime 到期时间
|
|
|
+ * @param upgradeType 升级类型:pay/gift/trial/consumption
|
|
|
+ * @param orderId 关联订单ID(可为 null)
|
|
|
+ */
|
|
|
+ private void syncMembershipToFamilyMembers(Long familyId, String levelCode, Date expireTime,
|
|
|
+ String upgradeType, Long orderId) {
|
|
|
+ if (familyId == null || levelCode == null || expireTime == null) return;
|
|
|
+ List<User> familyUsers = userMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<User>().eq(User::getFamilyId, familyId));
|
|
|
+ if (familyUsers == null || familyUsers.isEmpty()) return;
|
|
|
+
|
|
|
+ Date now = new Date();
|
|
|
+ for (User u : familyUsers) {
|
|
|
+ String fromLevel = u.getMemberLevel() != null ? u.getMemberLevel() : "FREE";
|
|
|
+ // 只有等级变化或到期时间延长时才写入(避免不必要的降级覆盖)
|
|
|
+ if (levelCode.equals(u.getMemberLevel())
|
|
|
+ && u.getMemberExpireTime() != null
|
|
|
+ && u.getMemberExpireTime().after(expireTime)) {
|
|
|
+ continue; // 已有同级更晚到期的会员,跳过
|
|
|
+ }
|
|
|
+ u.setMemberLevel(levelCode);
|
|
|
+ u.setMemberExpireTime(expireTime);
|
|
|
+ u.setUpdatedAt(now);
|
|
|
+ userMapper.updateById(u);
|
|
|
+
|
|
|
+ // 为每个成员创建升级记录
|
|
|
+ MemberUpgradeRecord record = new MemberUpgradeRecord();
|
|
|
+ record.setUserId(u.getId());
|
|
|
+ record.setFromLevel(fromLevel);
|
|
|
+ record.setToLevel(levelCode);
|
|
|
+ record.setUpgradeType(upgradeType);
|
|
|
+ record.setOrderId(orderId);
|
|
|
+ record.setExpireTime(expireTime);
|
|
|
+ record.setCreatedAt(now);
|
|
|
+ memberUpgradeRecordMapper.insert(record);
|
|
|
+ }
|
|
|
+ log.info("家庭会员全量同步完成: familyId={}, levelCode={}, 成员数={}", familyId, levelCode, familyUsers.size());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 方案B:将家庭所有成员降级为 FREE(退款、到期、家庭解散时调用)
|
|
|
+ * @param familyId 家庭ID
|
|
|
+ */
|
|
|
+ private void downgradeFamilyMembers(Long familyId) {
|
|
|
+ if (familyId == null) return;
|
|
|
+ List<User> familyUsers = userMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<User>().eq(User::getFamilyId, familyId));
|
|
|
+ if (familyUsers == null || familyUsers.isEmpty()) return;
|
|
|
+
|
|
|
+ Date now = new Date();
|
|
|
+ int downgraded = 0;
|
|
|
+ for (User u : familyUsers) {
|
|
|
+ if (!"FREE".equals(u.getMemberLevel())) {
|
|
|
+ u.setMemberLevel("FREE");
|
|
|
+ u.setMemberExpireTime(null);
|
|
|
+ u.setUpdatedAt(now);
|
|
|
+ userMapper.updateById(u);
|
|
|
+ downgraded++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (downgraded > 0) {
|
|
|
+ log.info("家庭全员降级 FREE: familyId={}, 降级人数={}", familyId, downgraded);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 方案B:新成员加入家庭时,继承家庭现有有效会员身份
|
|
|
+ * 由 FamilyMemberService.addMember() 调用
|
|
|
+ */
|
|
|
+ public void syncMembershipForNewMember(Long userId, Long familyId) {
|
|
|
+ if (userId == null || familyId == null) return;
|
|
|
+ FamilyMembership active = getActiveFamilyMembership(familyId);
|
|
|
+ if (active == null) return; // 家庭无有效会员
|
|
|
+
|
|
|
+ User u = userMapper.selectById(userId);
|
|
|
+ if (u == null) return;
|
|
|
+ String fromLevel = u.getMemberLevel() != null ? u.getMemberLevel() : "FREE";
|
|
|
+ // 只有当前等级更低或到期更早时才同步升级
|
|
|
+ if (active.getLevelCode().equals(u.getMemberLevel())
|
|
|
+ && u.getMemberExpireTime() != null
|
|
|
+ && u.getMemberExpireTime().after(active.getEndDate())) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ u.setMemberLevel(active.getLevelCode());
|
|
|
+ u.setMemberExpireTime(active.getEndDate());
|
|
|
+ u.setUpdatedAt(new Date());
|
|
|
+ userMapper.updateById(u);
|
|
|
+
|
|
|
+ MemberUpgradeRecord record = new MemberUpgradeRecord();
|
|
|
+ record.setUserId(userId);
|
|
|
+ record.setFromLevel(fromLevel);
|
|
|
+ record.setToLevel(active.getLevelCode());
|
|
|
+ record.setUpgradeType("family_sync");
|
|
|
+ record.setExpireTime(active.getEndDate());
|
|
|
+ record.setCreatedAt(new Date());
|
|
|
+ memberUpgradeRecordMapper.insert(record);
|
|
|
+
|
|
|
+ log.info("新成员继承家庭会员: userId={}, familyId={}, level={}", userId, familyId, active.getLevelCode());
|
|
|
+ }
|
|
|
+
|
|
|
// ==================== 会员升级与过期 ====================
|
|
|
|
|
|
/**
|
|
|
@@ -954,8 +1061,7 @@ public class MembershipService implements MembershipServiceInterface {
|
|
|
membershipMapper.updateById(membership);
|
|
|
}
|
|
|
|
|
|
- // 降级管理员:若无其他有效付费会员,降级为 FREE
|
|
|
- Family family = familyMapper.selectById(order.getFamilyId());
|
|
|
+ // 降级管理员:若无其他有效付费会员,降级全家为 FREE
|
|
|
if (family != null && family.getCreatorId() != null) {
|
|
|
User adminUser = userMapper.selectById(family.getCreatorId());
|
|
|
if (adminUser != null && order.getLevelCode().equals(adminUser.getMemberLevel())) {
|
|
|
@@ -966,11 +1072,9 @@ public class MembershipService implements MembershipServiceInterface {
|
|
|
.ne(FamilyMembership::getOrderNo, targetOrderNo)
|
|
|
.gt(FamilyMembership::getEndDate, new Date()));
|
|
|
if (activePaidCount == 0) {
|
|
|
- adminUser.setMemberLevel("FREE");
|
|
|
- adminUser.setMemberExpireTime(null);
|
|
|
- adminUser.setUpdatedAt(new Date());
|
|
|
- userMapper.updateById(adminUser);
|
|
|
- log.info("会员退款降级管理员: userId={}, familyId={}", adminUser.getId(), order.getFamilyId());
|
|
|
+ // 方案B:退款后无其他有效会员,全家降级
|
|
|
+ downgradeFamilyMembers(order.getFamilyId());
|
|
|
+ log.info("会员退款降级全家: userId={}, familyId={}", adminUser.getId(), order.getFamilyId());
|
|
|
}
|
|
|
}
|
|
|
}
|