Sfoglia il codice sorgente

个人设置,调整通知发送代码

zhangchen 1 settimana fa
parent
commit
ab798e184a

+ 35 - 2
alien-store/src/main/java/shop/alien/store/service/LifeCommentService.java

@@ -62,6 +62,8 @@ public class LifeCommentService {
 
     private final CommonCommentMapper commonCommentMapper;
 
+    private final LifeUserPersonalizationSettingService lifeUserPersonalizationSettingService;
+
     /**
      * 点赞操作
      * <p>
@@ -121,9 +123,14 @@ public class LifeCommentService {
             // 根据类型更新对应表的点赞数
             int updateResult = updateLikeCountByType(huifuId, type);
             
-            // 如果是动态类型,发送通知
+            // 如果是动态类型,按点赞用户个性化设置决定是否发送通知
             if (updateResult > 0 && CommonConstant.LIKE_TYPE_DYNAMICS.equals(type)) {
-                insertNotice(userId, huifuId, type);
+                Integer likerLifeUserId = resolveLifeUserIdFromLikeParam(userId);
+                boolean suppressNotice = likerLifeUserId != null
+                        && lifeUserPersonalizationSettingService.shouldSuppressLikeRelatedNotice(likerLifeUserId);
+                if (!suppressNotice) {
+                    insertNotice(userId, huifuId, type);
+                }
             }
             
             log.info("点赞操作完成,userId={},huifuId={},type={},更新结果={}", userId, huifuId, type, updateResult);
@@ -212,6 +219,32 @@ public class LifeCommentService {
     }
 
     /**
+     * 点赞接口传入的 userId(字符串)解析为 life_user.id:纯数字按主键;user_ 前缀按手机号查用户
+     */
+    private Integer resolveLifeUserIdFromLikeParam(String likeUserId) {
+        if (!StringUtils.hasText(likeUserId)) {
+            return null;
+        }
+        String trimmed = likeUserId.trim();
+        if (trimmed.startsWith("user_")) {
+            String phone = trimmed.substring("user_".length());
+            if (!StringUtils.hasText(phone)) {
+                return null;
+            }
+            LifeUser u = lifeUserMapper.selectOne(new LambdaQueryWrapper<LifeUser>()
+                    .eq(LifeUser::getUserPhone, phone)
+                    .eq(LifeUser::getDeleteFlag, 0)
+                    .last("LIMIT 1"));
+            return u != null ? u.getId() : null;
+        }
+        try {
+            return Integer.parseInt(trimmed);
+        } catch (NumberFormatException e) {
+            return null;
+        }
+    }
+
+    /**
      * 发送通知
      */
     private void insertNotice(String userId, String huifuId, String type) {

+ 24 - 0
alien-store/src/main/java/shop/alien/store/service/LifeUserPersonalizationSettingService.java

@@ -17,5 +17,29 @@ public interface LifeUserPersonalizationSettingService extends IService<LifeUser
 
     R<LifeUserPersonalizationSetting> getByUserId(Integer userId);
 
+    /**
+     * 查询用户个性化设置:优先 Redis;未命中则与 {@link #getByUserId} 一致查库(含无记录时初始化)并写入 Redis。
+     *
+     * @param userId life_user.id
+     * @return 实体;userId 为空或查库/初始化失败时返回 null
+     */
+    LifeUserPersonalizationSetting getByUserIdCacheAside(Integer userId);
+
+    /**
+     * 是否不应发送与点赞相关的通知:notifyReceiveMessage=0,或 notifyReceiveMessage=1 且 notifyLike=0。
+     *
+     * @param userId life_user.id
+     * @return userId 为空时 false(不拦截);有设置且满足上述条件时 true
+     */
+    boolean shouldSuppressLikeRelatedNotice(Integer userId);
+
+    /**
+     * 是否不应发送与关注相关的通知:notifyReceiveMessage=0,或 notifyReceiveMessage=1 且 notifyFollow=0。
+     *
+     * @param userId life_user.id(被关注方)
+     * @return userId 为空时 false(不拦截);有设置且满足上述条件时 true
+     */
+    boolean shouldSuppressFollowRelatedNotice(Integer userId);
+
     R<IPage<LifeUserPersonalizationSetting>> list(Integer pageNum, Integer pageSize, Integer userId);
 }

+ 26 - 1
alien-store/src/main/java/shop/alien/store/service/LifeUserService.java

@@ -74,6 +74,8 @@ public class LifeUserService extends ServiceImpl<LifeUserMapper, LifeUser> {
 
     private final SecondRiskControlRecordMapper secondRiskControlRecordMapper;
 
+    private final LifeUserPersonalizationSettingService lifeUserPersonalizationSettingService;
+
     @Autowired
     private RiskControlProperties riskControlProperties;
 
@@ -126,12 +128,35 @@ public class LifeUserService extends ServiceImpl<LifeUserMapper, LifeUser> {
             if (!CollectionUtils.isEmpty(userList)) {
                 notice.setBusinessId(userList.get(0).getId());
             }
-            lifeNoticeMapper.insert(notice);
+            Integer followedLifeUserId = resolveLifeUserIdFromFollowedId(fans.getFollowedId());
+            boolean suppressNotice = followedLifeUserId != null
+                    && lifeUserPersonalizationSettingService.shouldSuppressFollowRelatedNotice(followedLifeUserId);
+            if (!suppressNotice) {
+                lifeNoticeMapper.insert(notice);
+            }
         }
 
         return num;
     }
 
+    /**
+     * followedId 为 user_手机号 时解析为 life_user.id;店铺等非用户被关注方返回 null(不读个性化表,照常发通知)
+     */
+    private Integer resolveLifeUserIdFromFollowedId(String followedId) {
+        if (StringUtils.isBlank(followedId) || !followedId.startsWith("user_")) {
+            return null;
+        }
+        String phone = followedId.substring("user_".length());
+        if (StringUtils.isBlank(phone)) {
+            return null;
+        }
+        LifeUser u = lifeUserMapper.selectOne(new LambdaQueryWrapper<LifeUser>()
+                .eq(LifeUser::getUserPhone, phone)
+                .eq(LifeUser::getDeleteFlag, 0)
+                .last("LIMIT 1"));
+        return u != null ? u.getId() : null;
+    }
+
     public int cancelFans(LifeFans fans) {
         LambdaUpdateWrapper<LifeFans> wrapper = new LambdaUpdateWrapper<>();
         wrapper.eq(LifeFans::getFansId, fans.getFansId());

+ 93 - 0
alien-store/src/main/java/shop/alien/store/service/impl/LifeUserPersonalizationSettingServiceImpl.java

@@ -1,15 +1,19 @@
 package shop.alien.store.service.impl;
 
+import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.dao.DataIntegrityViolationException;
 import org.springframework.stereotype.Service;
 import shop.alien.entity.result.R;
 import shop.alien.entity.store.LifeUserPersonalizationSetting;
 import shop.alien.mapper.LifeUserPersonalizationSettingMapper;
+import shop.alien.store.config.BaseRedisService;
 import shop.alien.store.service.LifeUserPersonalizationSettingService;
 
 @Service
@@ -18,6 +22,12 @@ public class LifeUserPersonalizationSettingServiceImpl
         extends ServiceImpl<LifeUserPersonalizationSettingMapper, LifeUserPersonalizationSetting>
         implements LifeUserPersonalizationSettingService {
 
+    private static final String CACHE_KEY_PREFIX = "alien:store:life:user:personalization:";
+    private static final long CACHE_TTL_SECONDS = 7 * 24 * 3600L;
+
+    @Autowired
+    private BaseRedisService baseRedisService;
+
     @Override
     public R<String> add(LifeUserPersonalizationSetting setting) {
         log.info("LifeUserPersonalizationSettingServiceImpl.add, param={}", setting);
@@ -27,6 +37,7 @@ public class LifeUserPersonalizationSettingServiceImpl
         }
         boolean result = this.save(setting);
         if (result) {
+            invalidatePersonalizationCache(setting.getUserId());
             return R.success("新增成功");
         }
         return R.fail("新增失败");
@@ -35,8 +46,12 @@ public class LifeUserPersonalizationSettingServiceImpl
     @Override
     public R<String> deleteById(Integer id) {
         log.info("LifeUserPersonalizationSettingServiceImpl.deleteById, id={}", id);
+        LifeUserPersonalizationSetting old = id == null ? null : this.getById(id);
         boolean result = this.removeById(id);
         if (result) {
+            if (old != null) {
+                invalidatePersonalizationCache(old.getUserId());
+            }
             return R.success("删除成功");
         }
         return R.fail("删除失败");
@@ -87,6 +102,8 @@ public class LifeUserPersonalizationSettingServiceImpl
         }
         boolean result = this.updateById(setting);
         if (result) {
+            Integer uid = setting.getUserId() != null ? setting.getUserId() : existing.getUserId();
+            invalidatePersonalizationCache(uid);
             return R.success("更新成功");
         }
         return R.fail("更新失败");
@@ -154,6 +171,82 @@ public class LifeUserPersonalizationSettingServiceImpl
         }
     }
 
+    @Override
+    public LifeUserPersonalizationSetting getByUserIdCacheAside(Integer userId) {
+        if (userId == null) {
+            return null;
+        }
+        String key = cacheKey(userId);
+        String cached = baseRedisService.getString(key);
+        if (StringUtils.isNotEmpty(cached)) {
+            try {
+                LifeUserPersonalizationSetting parsed = JSON.parseObject(cached, LifeUserPersonalizationSetting.class);
+                if (parsed != null) {
+                    return parsed;
+                }
+            } catch (Exception e) {
+                log.warn("LifeUserPersonalizationSetting 缓存反序列化失败,删除 key,userId={}", userId, e);
+                baseRedisService.delete(key);
+            }
+        }
+        R<LifeUserPersonalizationSetting> r = getByUserId(userId);
+        if (!R.isSuccess(r) || r.getData() == null) {
+            return null;
+        }
+        LifeUserPersonalizationSetting data = r.getData();
+        try {
+            baseRedisService.setString(key, JSON.toJSONString(data), CACHE_TTL_SECONDS);
+        } catch (Exception e) {
+            log.warn("LifeUserPersonalizationSetting 写入缓存失败,userId={}", userId, e);
+        }
+        return data;
+    }
+
+    @Override
+    public boolean shouldSuppressLikeRelatedNotice(Integer userId) {
+        if (userId == null) {
+            return false;
+        }
+        LifeUserPersonalizationSetting s = getByUserIdCacheAside(userId);
+        if (s == null) {
+            return false;
+        }
+        Integer nrm = s.getNotifyReceiveMessage();
+        Integer nl = s.getNotifyLike();
+        if (nrm != null && nrm == 0) {
+            return true;
+        }
+        return nrm != null && nrm == 1 && nl != null && nl == 0;
+    }
+
+    @Override
+    public boolean shouldSuppressFollowRelatedNotice(Integer userId) {
+        if (userId == null) {
+            return false;
+        }
+        LifeUserPersonalizationSetting s = getByUserIdCacheAside(userId);
+        if (s == null) {
+            return false;
+        }
+        Integer nrm = s.getNotifyReceiveMessage();
+        Integer nf = s.getNotifyFollow();
+        if (nrm != null && nrm == 0) {
+            return true;
+        }
+        return nrm != null && nrm == 1 && nf != null && nf == 0;
+    }
+
+    private static String cacheKey(Integer userId) {
+        return CACHE_KEY_PREFIX + userId;
+    }
+
+    private void invalidatePersonalizationCache(Integer userId) {
+        if (userId == null) {
+            return;
+        }
+        baseRedisService.delete(cacheKey(userId));
+    }
+
     /** 与表默认值一致,便于无记录时落库 */
     private static LifeUserPersonalizationSetting buildDefaultForUser(Integer userId) {
         LifeUserPersonalizationSetting s = new LifeUserPersonalizationSetting();