|
@@ -352,69 +352,184 @@ public class MembershipService {
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 会员用户快照列表(用户维度,查 t_user + 当前会员)
|
|
* 会员用户快照列表(用户维度,查 t_user + 当前会员)
|
|
|
|
|
+ * <p>当前会员等级以 t_user_membership 表的活跃记录为准(取最高等级),
|
|
|
|
|
+ * 若无活跃记录则回退到 t_user.membership_level,再回退到 PLUS。
|
|
|
|
|
+ * 这样可兼容历史数据(t_user.membership_level 未同步更新的情况)。
|
|
|
*/
|
|
*/
|
|
|
public Page<MembershipUserResponse> listMembershipUsers(Integer pageNum, Integer pageSize,
|
|
public Page<MembershipUserResponse> listMembershipUsers(Integer pageNum, Integer pageSize,
|
|
|
String phone, String level) {
|
|
String phone, String level) {
|
|
|
|
|
+ MembershipLevel filterLevel = null;
|
|
|
|
|
+ if (level != null && !level.isBlank()) {
|
|
|
|
|
+ filterLevel = MembershipLevel.fromCode(level);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 如果按等级筛选,需要先从会员记录表找出符合条件的用户ID,再查用户表
|
|
|
|
|
+ if (filterLevel != null) {
|
|
|
|
|
+ Page<MembershipUserResponse> result = listMembershipUsersByLevel(pageNum, pageSize, phone, filterLevel);
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
Page<User> page = new Page<>(pageNum, pageSize);
|
|
Page<User> page = new Page<>(pageNum, pageSize);
|
|
|
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
|
|
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
|
|
|
if (phone != null && !phone.isBlank()) {
|
|
if (phone != null && !phone.isBlank()) {
|
|
|
wrapper.like(User::getPhone, phone);
|
|
wrapper.like(User::getPhone, phone);
|
|
|
}
|
|
}
|
|
|
- if (level != null && !level.isBlank()) {
|
|
|
|
|
- MembershipLevel ml = MembershipLevel.fromCode(level);
|
|
|
|
|
- if (ml != null) {
|
|
|
|
|
- wrapper.eq(User::getMembershipLevel, ml);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
wrapper.orderByDesc(User::getCreateTime);
|
|
wrapper.orderByDesc(User::getCreateTime);
|
|
|
Page<User> result = userMapper.selectPage(page, wrapper);
|
|
Page<User> result = userMapper.selectPage(page, wrapper);
|
|
|
|
|
|
|
|
- // 批量查活跃会员记录,取 source
|
|
|
|
|
|
|
+ // 批量查活跃会员记录,取最高等级
|
|
|
List<Long> userIds = result.getRecords().stream().map(User::getId).toList();
|
|
List<Long> userIds = result.getRecords().stream().map(User::getId).toList();
|
|
|
- Map<Long, String> sourceMap = userIds.isEmpty() ? Map.of()
|
|
|
|
|
- : userMembershipMapper.selectList(
|
|
|
|
|
- new LambdaQueryWrapper<UserMembership>()
|
|
|
|
|
- .in(UserMembership::getUserId, userIds)
|
|
|
|
|
- .eq(UserMembership::getStatus, 1))
|
|
|
|
|
- .stream().collect(Collectors.toMap(
|
|
|
|
|
- UserMembership::getUserId,
|
|
|
|
|
- UserMembership::getSource,
|
|
|
|
|
- (a, b) -> a));
|
|
|
|
|
-
|
|
|
|
|
- List<MembershipUserResponse> list = result.getRecords().stream().map(u -> {
|
|
|
|
|
- MembershipLevel currentLevel = u.getMembershipLevel() != null
|
|
|
|
|
- ? u.getMembershipLevel() : MembershipLevel.PLUS;
|
|
|
|
|
- String levelCode = currentLevel.getCode();
|
|
|
|
|
- boolean isPlus = currentLevel == MembershipLevel.PLUS;
|
|
|
|
|
- LocalDateTime expireAt = isPlus ? null : u.getMembershipExpireAt();
|
|
|
|
|
- int daysRemaining;
|
|
|
|
|
- if (isPlus) {
|
|
|
|
|
- daysRemaining = -1;
|
|
|
|
|
- } else if (expireAt != null && expireAt.isAfter(LocalDateTime.now())) {
|
|
|
|
|
- daysRemaining = (int) ChronoUnit.DAYS.between(LocalDateTime.now(), expireAt);
|
|
|
|
|
- } else {
|
|
|
|
|
- daysRemaining = 0;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ Map<Long, UserMembership> activeMap = loadActiveMemberships(userIds);
|
|
|
|
|
|
|
|
- return MembershipUserResponse.builder()
|
|
|
|
|
- .userId(u.getId())
|
|
|
|
|
- .phone(u.getPhone())
|
|
|
|
|
- .nickname(u.getNickname())
|
|
|
|
|
- .wechatNickname(u.getWechatNickname())
|
|
|
|
|
- .level(levelCode)
|
|
|
|
|
- .levelName(currentLevel.getDescription())
|
|
|
|
|
- .source(isPlus ? "SYSTEM" : sourceMap.getOrDefault(u.getId(), ""))
|
|
|
|
|
- .expireAt(expireAt)
|
|
|
|
|
- .daysRemaining(daysRemaining)
|
|
|
|
|
- .createTime(u.getCreateTime())
|
|
|
|
|
- .build();
|
|
|
|
|
- }).collect(Collectors.toList());
|
|
|
|
|
|
|
+ List<MembershipUserResponse> list = result.getRecords().stream()
|
|
|
|
|
+ .map(u -> toMembershipUserResponse(u, activeMap.get(u.getId())))
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
|
|
|
Page<MembershipUserResponse> responsePage = new Page<>(pageNum, pageSize, result.getTotal());
|
|
Page<MembershipUserResponse> responsePage = new Page<>(pageNum, pageSize, result.getTotal());
|
|
|
responsePage.setRecords(list);
|
|
responsePage.setRecords(list);
|
|
|
return responsePage;
|
|
return responsePage;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 按等级筛选会员用户列表
|
|
|
|
|
+ * <p>筛选逻辑:用户当前最高等级活跃记录等于筛选等级时才命中。
|
|
|
|
|
+ * 例如筛选 PRO 时,若用户同时有活跃 ULTRA 记录,则该用户归为 ULTRA 而非 PRO。
|
|
|
|
|
+ */
|
|
|
|
|
+ private Page<MembershipUserResponse> listMembershipUsersByLevel(Integer pageNum, Integer pageSize,
|
|
|
|
|
+ String phone, MembershipLevel filterLevel) {
|
|
|
|
|
+ // 查出所有活跃会员记录
|
|
|
|
|
+ LambdaQueryWrapper<UserMembership> mWrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
+ mWrapper.eq(UserMembership::getStatus, 1)
|
|
|
|
|
+ .and(w -> w.isNull(UserMembership::getEffectiveTo)
|
|
|
|
|
+ .or().gt(UserMembership::getEffectiveTo, LocalDateTime.now()));
|
|
|
|
|
+ List<UserMembership> memberships = userMembershipMapper.selectList(mWrapper);
|
|
|
|
|
+ if (memberships.isEmpty()) {
|
|
|
|
|
+ Page<MembershipUserResponse> emptyPage = new Page<>(pageNum, pageSize, 0);
|
|
|
|
|
+ emptyPage.setRecords(Collections.emptyList());
|
|
|
|
|
+ return emptyPage;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 按 userId 分组,取每个用户最高等级的活跃记录
|
|
|
|
|
+ Map<Long, UserMembership> topMap = new HashMap<>();
|
|
|
|
|
+ for (UserMembership m : memberships) {
|
|
|
|
|
+ UserMembership existing = topMap.get(m.getUserId());
|
|
|
|
|
+ if (existing == null || m.getLevel().getWeight() > existing.getLevel().getWeight()) {
|
|
|
|
|
+ topMap.put(m.getUserId(), m);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 只保留最高等级等于筛选等级的用户
|
|
|
|
|
+ Map<Long, UserMembership> matchedMap = new HashMap<>();
|
|
|
|
|
+ for (Map.Entry<Long, UserMembership> entry : topMap.entrySet()) {
|
|
|
|
|
+ if (entry.getValue().getLevel() == filterLevel) {
|
|
|
|
|
+ matchedMap.put(entry.getKey(), entry.getValue());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (matchedMap.isEmpty()) {
|
|
|
|
|
+ Page<MembershipUserResponse> emptyPage = new Page<>(pageNum, pageSize, 0);
|
|
|
|
|
+ emptyPage.setRecords(Collections.emptyList());
|
|
|
|
|
+ return emptyPage;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ List<Long> userIds = new java.util.ArrayList<>(matchedMap.keySet());
|
|
|
|
|
+
|
|
|
|
|
+ // 按手机号筛选用户
|
|
|
|
|
+ LambdaQueryWrapper<User> uWrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
+ uWrapper.in(User::getId, userIds);
|
|
|
|
|
+ if (phone != null && !phone.isBlank()) {
|
|
|
|
|
+ uWrapper.like(User::getPhone, phone);
|
|
|
|
|
+ }
|
|
|
|
|
+ uWrapper.orderByDesc(User::getCreateTime);
|
|
|
|
|
+
|
|
|
|
|
+ Page<User> page = new Page<>(pageNum, pageSize);
|
|
|
|
|
+ Page<User> userPage = userMapper.selectPage(page, uWrapper);
|
|
|
|
|
+
|
|
|
|
|
+ List<MembershipUserResponse> list = userPage.getRecords().stream()
|
|
|
|
|
+ .map(u -> toMembershipUserResponse(u, matchedMap.get(u.getId())))
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+
|
|
|
|
|
+ Page<MembershipUserResponse> responsePage = new Page<>(pageNum, pageSize, userPage.getTotal());
|
|
|
|
|
+ responsePage.setRecords(list);
|
|
|
|
|
+ return responsePage;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 批量加载用户的活跃会员记录,返回 userId -> 最高等级会员记录 的映射
|
|
|
|
|
+ */
|
|
|
|
|
+ private Map<Long, UserMembership> loadActiveMemberships(List<Long> userIds) {
|
|
|
|
|
+ if (userIds == null || userIds.isEmpty()) {
|
|
|
|
|
+ return Collections.emptyMap();
|
|
|
|
|
+ }
|
|
|
|
|
+ List<UserMembership> actives = userMembershipMapper.selectActiveByUserIds(userIds);
|
|
|
|
|
+ Map<Long, UserMembership> map = new HashMap<>();
|
|
|
|
|
+ for (UserMembership m : actives) {
|
|
|
|
|
+ UserMembership existing = map.get(m.getUserId());
|
|
|
|
|
+ if (existing == null || m.getLevel().getWeight() > existing.getLevel().getWeight()) {
|
|
|
|
|
+ map.put(m.getUserId(), m);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return map;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 将用户和活跃会员记录组装为响应对象
|
|
|
|
|
+ * <p>优先使用会员记录表的等级和过期时间;若无活跃记录,回退到用户表字段。
|
|
|
|
|
+ * 高级会员过期后(effective_to 早于当前时间)降级显示为普通会员。
|
|
|
|
|
+ */
|
|
|
|
|
+ private MembershipUserResponse toMembershipUserResponse(User u, UserMembership active) {
|
|
|
|
|
+ MembershipLevel currentLevel;
|
|
|
|
|
+ LocalDateTime expireAt;
|
|
|
|
|
+ String source;
|
|
|
|
|
+
|
|
|
|
|
+ LocalDateTime now = LocalDateTime.now();
|
|
|
|
|
+ if (active != null && active.getLevel() != MembershipLevel.PLUS
|
|
|
|
|
+ && active.getEffectiveTo() != null && !active.getEffectiveTo().isAfter(now)) {
|
|
|
|
|
+ // 高级会员已过期:降级为普通会员
|
|
|
|
|
+ currentLevel = MembershipLevel.PLUS;
|
|
|
|
|
+ expireAt = null;
|
|
|
|
|
+ source = "SYSTEM";
|
|
|
|
|
+ } else if (active != null) {
|
|
|
|
|
+ currentLevel = active.getLevel();
|
|
|
|
|
+ expireAt = active.getEffectiveTo();
|
|
|
|
|
+ source = active.getSource();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ currentLevel = u.getMembershipLevel() != null ? u.getMembershipLevel() : MembershipLevel.PLUS;
|
|
|
|
|
+ // 用户表等级为高级但无活跃记录,说明已过期,降级为普通会员
|
|
|
|
|
+ if (currentLevel != MembershipLevel.PLUS) {
|
|
|
|
|
+ currentLevel = MembershipLevel.PLUS;
|
|
|
|
|
+ }
|
|
|
|
|
+ expireAt = null;
|
|
|
|
|
+ source = "SYSTEM";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ String levelCode = currentLevel.getCode();
|
|
|
|
|
+ boolean isPlus = currentLevel == MembershipLevel.PLUS;
|
|
|
|
|
+ if (isPlus) {
|
|
|
|
|
+ expireAt = null;
|
|
|
|
|
+ }
|
|
|
|
|
+ int daysRemaining;
|
|
|
|
|
+ if (isPlus) {
|
|
|
|
|
+ daysRemaining = -1;
|
|
|
|
|
+ } else if (expireAt != null && expireAt.isAfter(now)) {
|
|
|
|
|
+ daysRemaining = (int) ChronoUnit.DAYS.between(now, expireAt);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ daysRemaining = 0;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return MembershipUserResponse.builder()
|
|
|
|
|
+ .userId(u.getId())
|
|
|
|
|
+ .phone(u.getPhone())
|
|
|
|
|
+ .nickname(u.getNickname())
|
|
|
|
|
+ .wechatNickname(u.getWechatNickname())
|
|
|
|
|
+ .level(levelCode)
|
|
|
|
|
+ .levelName(currentLevel.getDescription())
|
|
|
|
|
+ .source(source)
|
|
|
|
|
+ .expireAt(expireAt)
|
|
|
|
|
+ .daysRemaining(daysRemaining)
|
|
|
|
|
+ .createTime(u.getCreateTime())
|
|
|
|
|
+ .build();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private MembershipResponse toResponse(UserMembership membership) {
|
|
private MembershipResponse toResponse(UserMembership membership) {
|
|
|
if (membership == null) {
|
|
if (membership == null) {
|
|
|
return null;
|
|
return null;
|
|
@@ -493,33 +608,96 @@ public class MembershipService {
|
|
|
.isNotNull(UserMembership::getEffectiveTo)
|
|
.isNotNull(UserMembership::getEffectiveTo)
|
|
|
.lt(UserMembership::getEffectiveTo, LocalDateTime.now()));
|
|
.lt(UserMembership::getEffectiveTo, LocalDateTime.now()));
|
|
|
|
|
|
|
|
- if (expired.isEmpty()) {
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ if (!expired.isEmpty()) {
|
|
|
|
|
+ Set<Long> affectedUserIds = new HashSet<>();
|
|
|
|
|
+ for (UserMembership m : expired) {
|
|
|
|
|
+ m.setStatus(0);
|
|
|
|
|
+ userMembershipMapper.updateById(m);
|
|
|
|
|
+ affectedUserIds.add(m.getUserId());
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- Set<Long> affectedUserIds = new HashSet<>();
|
|
|
|
|
- for (UserMembership m : expired) {
|
|
|
|
|
- m.setStatus(0);
|
|
|
|
|
- userMembershipMapper.updateById(m);
|
|
|
|
|
- affectedUserIds.add(m.getUserId());
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 对每个受影响的用户,检查是否还有其他有效会员
|
|
|
|
|
- for (Long userId : affectedUserIds) {
|
|
|
|
|
- UserMembership active = userMembershipMapper.selectActiveByUserId(userId);
|
|
|
|
|
- if (active == null) {
|
|
|
|
|
- // 无有效会员,降级为普通会员
|
|
|
|
|
- User user = userMapper.selectById(userId);
|
|
|
|
|
- if (user != null && user.getMembershipLevel() != MembershipLevel.PLUS) {
|
|
|
|
|
- user.setMembershipLevel(MembershipLevel.PLUS);
|
|
|
|
|
- user.setMembershipExpireAt(null);
|
|
|
|
|
- userMapper.updateById(user);
|
|
|
|
|
- log.info("用户{}会员已到期,降级为普通会员", userId);
|
|
|
|
|
|
|
+ // 对每个受影响的用户,检查是否还有其他有效会员
|
|
|
|
|
+ for (Long userId : affectedUserIds) {
|
|
|
|
|
+ UserMembership active = userMembershipMapper.selectActiveByUserId(userId);
|
|
|
|
|
+ if (active == null) {
|
|
|
|
|
+ // 无有效会员,降级为普通会员
|
|
|
|
|
+ User user = userMapper.selectById(userId);
|
|
|
|
|
+ if (user != null && user.getMembershipLevel() != MembershipLevel.PLUS) {
|
|
|
|
|
+ user.setMembershipLevel(MembershipLevel.PLUS);
|
|
|
|
|
+ user.setMembershipExpireAt(null);
|
|
|
|
|
+ userMapper.updateById(user);
|
|
|
|
|
+ log.info("用户{}会员已到期,降级为普通会员", userId);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+ log.info("处理过期会员记录: {}条,涉及用户: {}个", expired.size(), affectedUserIds.size());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- log.info("处理过期会员记录: {}条,涉及用户: {}个", expired.size(), affectedUserIds.size());
|
|
|
|
|
|
|
+ // 修复历史数据:t_user_membership 有活跃记录但 t_user.membership_level 不一致
|
|
|
|
|
+ fixInconsistentUserMembershipLevel();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 修复历史数据:当 t_user_membership 有活跃记录但 t_user.membership_level 不一致时,
|
|
|
|
|
+ * 将 t_user.membership_level 同步为活跃记录中的最高等级。
|
|
|
|
|
+ * 若无活跃的高级会员记录,则降级为普通会员。
|
|
|
|
|
+ */
|
|
|
|
|
+ private void fixInconsistentUserMembershipLevel() {
|
|
|
|
|
+ // 查出所有有活跃会员记录的用户ID
|
|
|
|
|
+ List<UserMembership> actives = userMembershipMapper.selectList(
|
|
|
|
|
+ new LambdaQueryWrapper<UserMembership>()
|
|
|
|
|
+ .eq(UserMembership::getStatus, 1)
|
|
|
|
|
+ .and(w -> w.isNull(UserMembership::getEffectiveTo)
|
|
|
|
|
+ .or().gt(UserMembership::getEffectiveTo, LocalDateTime.now())));
|
|
|
|
|
+
|
|
|
|
|
+ // 按 userId 分组,取每个用户最高等级
|
|
|
|
|
+ Map<Long, UserMembership> topMap = new HashMap<>();
|
|
|
|
|
+ for (UserMembership m : actives) {
|
|
|
|
|
+ UserMembership existing = topMap.get(m.getUserId());
|
|
|
|
|
+ if (existing == null || m.getLevel().getWeight() > existing.getLevel().getWeight()) {
|
|
|
|
|
+ topMap.put(m.getUserId(), m);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 查出 t_user.membership_level 为高级会员的所有用户,检查是否需要降级
|
|
|
|
|
+ List<User> highLevelUsers = userMapper.selectList(
|
|
|
|
|
+ new LambdaQueryWrapper<User>()
|
|
|
|
|
+ .isNotNull(User::getMembershipLevel)
|
|
|
|
|
+ .ne(User::getMembershipLevel, MembershipLevel.PLUS));
|
|
|
|
|
+ int fixed = 0;
|
|
|
|
|
+ for (User user : highLevelUsers) {
|
|
|
|
|
+ UserMembership top = topMap.get(user.getId());
|
|
|
|
|
+ boolean needUpdate = false;
|
|
|
|
|
+ if (top == null) {
|
|
|
|
|
+ // 无活跃高级会员记录,降级为普通会员
|
|
|
|
|
+ user.setMembershipLevel(MembershipLevel.PLUS);
|
|
|
|
|
+ user.setMembershipExpireAt(null);
|
|
|
|
|
+ needUpdate = true;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 等级不一致(无论升降级)都需要同步
|
|
|
|
|
+ if (!java.util.Objects.equals(user.getMembershipLevel(), top.getLevel())) {
|
|
|
|
|
+ user.setMembershipLevel(top.getLevel());
|
|
|
|
|
+ needUpdate = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ LocalDateTime expectedExpire = top.getEffectiveTo();
|
|
|
|
|
+ if (top.getLevel() == MembershipLevel.PLUS) {
|
|
|
|
|
+ expectedExpire = null;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!java.util.Objects.equals(user.getMembershipExpireAt(), expectedExpire)) {
|
|
|
|
|
+ user.setMembershipExpireAt(expectedExpire);
|
|
|
|
|
+ needUpdate = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (needUpdate) {
|
|
|
|
|
+ userMapper.updateById(user);
|
|
|
|
|
+ fixed++;
|
|
|
|
|
+ log.info("修复用户{}会员等级不一致: -> {}",
|
|
|
|
|
+ user.getId(), user.getMembershipLevel());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (fixed > 0) {
|
|
|
|
|
+ log.info("修复历史会员等级不一致数据: {}个用户", fixed);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// ==================== 等级查询(原 UserLevelService,已合并) ====================
|
|
// ==================== 等级查询(原 UserLevelService,已合并) ====================
|
|
@@ -623,7 +801,9 @@ public class MembershipService {
|
|
|
}
|
|
}
|
|
|
boolean premium = resp.getLevelCode() != null && !"PLUS".equals(resp.getLevelCode());
|
|
boolean premium = resp.getLevelCode() != null && !"PLUS".equals(resp.getLevelCode());
|
|
|
if (!premium) { resp.setMembershipExpireAt(null); resp.setMembershipDaysRemaining(-1); return; }
|
|
if (!premium) { resp.setMembershipExpireAt(null); resp.setMembershipDaysRemaining(-1); return; }
|
|
|
- LocalDateTime expire = user.getMembershipExpireAt();
|
|
|
|
|
|
|
+ // 以会员记录表的活跃记录为准获取过期时间
|
|
|
|
|
+ UserMembership active = userMembershipMapper.selectActiveByUserId(user.getId());
|
|
|
|
|
+ LocalDateTime expire = active != null ? active.getEffectiveTo() : user.getMembershipExpireAt();
|
|
|
if (expire != null && expire.isAfter(LocalDateTime.now())) {
|
|
if (expire != null && expire.isAfter(LocalDateTime.now())) {
|
|
|
resp.setMembershipExpireAt(expire);
|
|
resp.setMembershipExpireAt(expire);
|
|
|
resp.setMembershipDaysRemaining((int) ChronoUnit.DAYS.between(LocalDateTime.now(), expire));
|
|
resp.setMembershipDaysRemaining((int) ChronoUnit.DAYS.between(LocalDateTime.now(), expire));
|