|
|
@@ -260,6 +260,9 @@ public class MembershipService implements MembershipServiceInterface {
|
|
|
* 创建订单
|
|
|
*/
|
|
|
public PaymentOrderDTO createOrder(Long userId, Long familyId, String levelCode, String paymentType, String period, Long userCouponId) {
|
|
|
+ if (familyId == null) {
|
|
|
+ throw new RuntimeException("请先创建或加入家庭后再购买会员");
|
|
|
+ }
|
|
|
MembershipLevel level = levelMapper.selectOne(
|
|
|
new LambdaQueryWrapper<MembershipLevel>()
|
|
|
.eq(MembershipLevel::getLevelCode, levelCode)
|
|
|
@@ -425,7 +428,16 @@ public class MembershipService implements MembershipServiceInterface {
|
|
|
return true;
|
|
|
}
|
|
|
if ("paid".equals(order.getStatus())) {
|
|
|
- return true;
|
|
|
+ // 幂等增强:已 paid 但无开通记录(历史 families.creator_id 缺失导致开通失败)→ 补开通
|
|
|
+ Long membershipCount = membershipMapper.selectCount(
|
|
|
+ new LambdaQueryWrapper<FamilyMembership>()
|
|
|
+ .eq(FamilyMembership::getOrderNo, orderNo)
|
|
|
+ .eq(FamilyMembership::getPaymentStatus, "paid"));
|
|
|
+ if (membershipCount != null && membershipCount > 0) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ log.info("订单已paid但无开通记录, 触发补开通: orderNo={}", orderNo);
|
|
|
+ // 不短路,继续走下方开通逻辑
|
|
|
}
|
|
|
|
|
|
// 标记该期已付
|
|
|
@@ -490,12 +502,13 @@ public class MembershipService implements MembershipServiceInterface {
|
|
|
couponService.markUsed(order.getUserCouponId(), order.getId());
|
|
|
}
|
|
|
|
|
|
- // 查找该家庭的创建者(家庭管理员)
|
|
|
- Family family = familyMapper.selectById(order.getFamilyId());
|
|
|
- if (family == null || family.getCreatorId() == null) {
|
|
|
+ // 查找该家庭的创建者(家庭管理员),creator_id 缺失时回退 users.family_id
|
|
|
+ Long adminUserId = resolveFamilyAdminUserId(order.getFamilyId());
|
|
|
+ if (adminUserId == null) {
|
|
|
+ log.warn("会员开通失败: 家庭无关联用户, familyId={}, orderNo={}",
|
|
|
+ order.getFamilyId(), order.getOrderNo());
|
|
|
return false;
|
|
|
}
|
|
|
- Long adminUserId = family.getCreatorId();
|
|
|
User adminUser = userMapper.selectById(adminUserId);
|
|
|
if (adminUser == null) {
|
|
|
return false;
|
|
|
@@ -558,6 +571,39 @@ public class MembershipService implements MembershipServiceInterface {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 解析家庭管理员用户ID。
|
|
|
+ * 优先 families.creator_id;缺失时回退 users.family_id
|
|
|
+ * (优先 is_family_admin=true 的用户,否则取任一 openid 非空用户)。
|
|
|
+ * 用于会员开通/虚拟支付兜底任务(早期 families.creator_id 从未写入,需回退)。
|
|
|
+ */
|
|
|
+ public Long resolveFamilyAdminUserId(Long familyId) {
|
|
|
+ if (familyId == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ Family family = familyMapper.selectById(familyId);
|
|
|
+ if (family != null && family.getCreatorId() != null) {
|
|
|
+ return family.getCreatorId();
|
|
|
+ }
|
|
|
+ // 回退:从 users.family_id 反查家庭成员
|
|
|
+ List<User> members = userMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<User>()
|
|
|
+ .eq(User::getFamilyId, familyId)
|
|
|
+ .isNotNull(User::getOpenid)
|
|
|
+ .ne(User::getOpenid, "")
|
|
|
+ );
|
|
|
+ if (members == null || members.isEmpty()) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ // 优先家庭管理员,其次任一成员
|
|
|
+ for (User u : members) {
|
|
|
+ if (Boolean.TRUE.equals(u.getIsFamilyAdmin())) {
|
|
|
+ return u.getId();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return members.get(0).getId();
|
|
|
+ }
|
|
|
+
|
|
|
// ==================== 会员升级与过期 ====================
|
|
|
|
|
|
/**
|