|
|
@@ -2,8 +2,10 @@ package com.etotem.cfc.service;
|
|
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.etotem.cfc.entity.Badge;
|
|
|
+import com.etotem.cfc.entity.FamilyMember;
|
|
|
import com.etotem.cfc.entity.MemberBadge;
|
|
|
import com.etotem.cfc.mapper.BadgeMapper;
|
|
|
+import com.etotem.cfc.mapper.FamilyMemberMapper;
|
|
|
import com.etotem.cfc.mapper.MemberBadgeMapper;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
@@ -25,6 +27,12 @@ public class BadgeService {
|
|
|
@Resource
|
|
|
private MemberBadgeMapper memberBadgeMapper;
|
|
|
|
|
|
+ @Resource
|
|
|
+ private FamilyMemberMapper familyMemberMapper;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private NotificationDispatchService notificationDispatchService;
|
|
|
+
|
|
|
// ===== 勋章定义管理 =====
|
|
|
|
|
|
public List<Badge> getAllBadges() {
|
|
|
@@ -101,6 +109,62 @@ public class BadgeService {
|
|
|
}
|
|
|
|
|
|
memberBadgeMapper.insert(cb);
|
|
|
+
|
|
|
+ // C-10 勋章解锁提醒:授予成功后向成员(或代管用户)写站内通知(type=badge_unlock)
|
|
|
+ sendBadgeUnlockNotice(memberId, badge);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * C-10 勋章解锁提醒。
|
|
|
+ * <p>
|
|
|
+ * 授予成功后写 {@code user_notifications}(type=badge_unlock):
|
|
|
+ * <ul>
|
|
|
+ * <li>可登录成员(family_members.userId 非空)→ 通知本人;</li>
|
|
|
+ * <li>不可登录成员(userId 为空)→ 由同家庭能登录成员(家庭管理员优先)代收;</li>
|
|
|
+ * <li>通知失败不阻断授予(授予已在同事务提交,仅记录警告)。</li>
|
|
|
+ * </ul>
|
|
|
+ * 模板 {@code notification_templates} 无 badge_unlock 记录时回退默认文案(见
|
|
|
+ * {@link NotificationDispatchService#sendByTemplate})。
|
|
|
+ */
|
|
|
+ private void sendBadgeUnlockNotice(Long memberId, Badge badge) {
|
|
|
+ try {
|
|
|
+ FamilyMember member = familyMemberMapper.selectById(memberId);
|
|
|
+ if (member == null) {
|
|
|
+ log.warn("勋章解锁通知跳过:memberId={} 不存在", memberId);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ Long targetUserId = member.getUserId();
|
|
|
+ if (targetUserId == null) {
|
|
|
+ // 不可登录成员:由同家庭能登录成员(家庭管理员优先)代收
|
|
|
+ FamilyMember proxy = familyMemberMapper.selectOne(
|
|
|
+ new LambdaQueryWrapper<FamilyMember>()
|
|
|
+ .eq(FamilyMember::getFamilyId, member.getFamilyId())
|
|
|
+ .isNotNull(FamilyMember::getUserId)
|
|
|
+ .last("ORDER BY (is_admin = 1) DESC, id ASC LIMIT 1"));
|
|
|
+ if (proxy != null) {
|
|
|
+ targetUserId = proxy.getUserId();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (targetUserId == null) {
|
|
|
+ log.warn("勋章解锁通知跳过:memberId={} 无可通知用户", memberId);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ String badgeName = (badge.getName() != null && !badge.getName().isEmpty())
|
|
|
+ ? badge.getName()
|
|
|
+ : (badge.getBadgeId() != null ? badge.getBadgeId() : "新勋章");
|
|
|
+ notificationDispatchService.sendByTemplate(
|
|
|
+ "badge_unlock",
|
|
|
+ targetUserId,
|
|
|
+ NotificationDispatchService.vars("badgeName", badgeName),
|
|
|
+ "badge",
|
|
|
+ badge.getId(),
|
|
|
+ "勋章解锁",
|
|
|
+ "恭喜,您解锁了勋章「{badgeName}」,继续加油!");
|
|
|
+ log.info("勋章解锁通知已发送: memberId={}, badgeId={}, userId={}", memberId, badge.getId(), targetUserId);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("勋章解锁通知发送失败 memberId={}, badgeId={}, error={}",
|
|
|
+ memberId, badge.getId(), e.getMessage());
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// ===== 家庭成员勋章查询 =====
|