Authored by mlge

种草--点赞--增粉修改 && 清除话题缓存

@@ -207,6 +207,13 @@ public class GrassArticleServiceImpl implements IGrassArticleService{ @@ -207,6 +207,13 @@ public class GrassArticleServiceImpl implements IGrassArticleService{
207 grassArticleTopic.setArticleId(article.getId()); 207 grassArticleTopic.setArticleId(article.getId());
208 grassArticleTopic.setCreateTime(now); 208 grassArticleTopic.setCreateTime(now);
209 grassArticleTopicDao.insertArticleTopic(grassArticleTopic); 209 grassArticleTopicDao.insertArticleTopic(grassArticleTopic);
  210 + //后期增加(清除话题缓存)
  211 + GrassCacheReq cacheReq = new GrassCacheReq();
  212 + cacheReq.setClearCode(1005);
  213 + cacheReq.setTopicId(topicId);
  214 + logger.info("updateArticle clear topicCache topicId={}",topicId);
  215 + grassRefreshCacheService.refreshGrassCache(cacheReq);
  216 +
210 } 217 }
211 }catch (Exception e){ 218 }catch (Exception e){
212 logger.warn("publishArticle ,grassArticleTopicDao insertArticleTopic error, uid is {}, e is {}", req.getAuthorUid(), e); 219 logger.warn("publishArticle ,grassArticleTopicDao insertArticleTopic error, uid is {}, e is {}", req.getAuthorUid(), e);
@@ -470,7 +477,6 @@ public class GrassArticleServiceImpl implements IGrassArticleService{ @@ -470,7 +477,6 @@ public class GrassArticleServiceImpl implements IGrassArticleService{
470 if(isRecommend == 1 && articleInfo.getArticleType() == 4 && articleInfo.getRemRewardFlag() == 0){ 477 if(isRecommend == 1 && articleInfo.getArticleType() == 4 && articleInfo.getRemRewardFlag() == 0){
471 sendRemReward(articleInfo); 478 sendRemReward(articleInfo);
472 } 479 }
473 -  
474 } 480 }
475 if(isTop !=null){ 481 if(isTop !=null){
476 grassArticle.setIsTop(isTop); 482 grassArticle.setIsTop(isTop);
@@ -507,12 +513,24 @@ public class GrassArticleServiceImpl implements IGrassArticleService{ @@ -507,12 +513,24 @@ public class GrassArticleServiceImpl implements IGrassArticleService{
507 grassArticle.setAuthorizeAccount(req.getAuthorizeAccount()); 513 grassArticle.setAuthorizeAccount(req.getAuthorizeAccount());
508 grassArticle.setAuthTime(System.currentTimeMillis()); 514 grassArticle.setAuthTime(System.currentTimeMillis());
509 grassArticleDao.updateByPrimaryKeySelective(grassArticle); 515 grassArticleDao.updateByPrimaryKeySelective(grassArticle);
510 - //审核通过 或者不通过 需要修改article_label表--便于前台标签相关的文章 分页查询 516 + //审核通过 或者不通过 需要修改article_label表--便于前台标签相关的文章 分页查询(一期)
511 GrassArticleLabel grassArticleLabel = new GrassArticleLabel(); 517 GrassArticleLabel grassArticleLabel = new GrassArticleLabel();
512 grassArticleLabel.setArticleId(articleId); 518 grassArticleLabel.setArticleId(articleId);
513 grassArticleLabel.setAuthStatus(authStatus);//审核状态 519 grassArticleLabel.setAuthStatus(authStatus);//审核状态
514 grassArticleLabelDao.updateByPrimaryKeySelective(grassArticleLabel); 520 grassArticleLabelDao.updateByPrimaryKeySelective(grassArticleLabel);
515 logger.info("updateArticle changeAuthStatus success! req={}",req); 521 logger.info("updateArticle changeAuthStatus success! req={}",req);
  522 +
  523 + // //后期新增加的(审核后 话题详情页实时刷新)--清理话题缓存
  524 + GrassCacheReq cacheReq = new GrassCacheReq();
  525 + GrassArticleTopic articleTopic = grassArticleTopicDao.selectByArticleId(grassArticle.getId());
  526 + if(articleTopic != null){
  527 + Integer topicId = articleTopic.getTopicId();
  528 + cacheReq.setClearCode(1005);
  529 + cacheReq.setTopicId(topicId);
  530 + logger.info("updateArticle clear topicCache topicId={}",topicId);
  531 + grassRefreshCacheService.refreshGrassCache(cacheReq);
  532 + }
  533 +
516 } 534 }
517 535
518 //定时发布 536 //定时发布
@@ -809,6 +827,15 @@ public class GrassArticleServiceImpl implements IGrassArticleService{ @@ -809,6 +827,15 @@ public class GrassArticleServiceImpl implements IGrassArticleService{
809 grassArticleTopic.setArticleId(articleId); 827 grassArticleTopic.setArticleId(articleId);
810 grassArticleTopic.setCreateTime(time); 828 grassArticleTopic.setCreateTime(time);
811 grassArticleTopicDao.insertArticleTopic(grassArticleTopic); 829 grassArticleTopicDao.insertArticleTopic(grassArticleTopic);
  830 + if(type == 2){ //2 编辑后直接发布
  831 + //后期增加(清除缓存)
  832 + GrassCacheReq cacheReq = new GrassCacheReq();
  833 + cacheReq.setClearCode(1005);
  834 + cacheReq.setTopicId(topicId);
  835 + logger.info("updateArticle clear topicCache topicId={}",topicId);
  836 + grassRefreshCacheService.refreshGrassCache(cacheReq);
  837 +
  838 + }
812 } 839 }
813 }catch (Exception e){ 840 }catch (Exception e){
814 logger.warn("publishArticle ,grassArticleTopicDao insertArticleTopic error, uid is {}, e is {}", req.getAuthorUid(), e); 841 logger.warn("publishArticle ,grassArticleTopicDao insertArticleTopic error, uid is {}, e is {}", req.getAuthorUid(), e);
@@ -40,8 +40,10 @@ public class GrassRefreshCacheServiceImpl implements IGrassRefreshCacheService{ @@ -40,8 +40,10 @@ public class GrassRefreshCacheServiceImpl implements IGrassRefreshCacheService{
40 String elementId = reqVO.getElementId(); 40 String elementId = reqVO.getElementId();
41 int clearCode = reqVO.getClearCode(); 41 int clearCode = reqVO.getClearCode();
42 int uid = reqVO.getUid(); 42 int uid = reqVO.getUid();
  43 + Integer topicId = reqVO.getTopicId();
43 try{ 44 try{
44 - String url = apiUrl + "?method=clear.grass.cache&elementId=" + elementId + "&clearCode=" + clearCode + "&uid=" + uid+"&userType=" +reqVO.getUserType(); 45 + String url = apiUrl + "?method=clear.grass.cache&elementId=" + elementId + "&clearCode=" + clearCode + "&uid=" + uid+"&userType=" +reqVO.getUserType()
  46 + + "&topicId=" + topicId;
45 logger.info("before refreshGrassCache, url is: {}, reqVo is {}", url, reqVO); 47 logger.info("before refreshGrassCache, url is: {}, reqVo is {}", url, reqVO);
46 serviceCaller.get("app.clearGrassCache", url, null, String.class, null); 48 serviceCaller.get("app.clearGrassCache", url, null, String.class, null);
47 }catch (Exception e){ 49 }catch (Exception e){
1 package com.yohobuy.platform.grass.service.impl; 1 package com.yohobuy.platform.grass.service.impl;
2 2
  3 +
3 import com.yoho.core.config.ConfigReader; 4 import com.yoho.core.config.ConfigReader;
  5 +import com.yoho.core.rest.client.ServiceCaller;
  6 +import com.yoho.service.model.sns.model.enums.GrassInboxBusinessTypeEnum;
  7 +import com.yoho.service.model.sns.request.GrassInBoxAddReq;
4 import com.yohobuy.platform.common.enums.GrassUserTypeEnum; 8 import com.yohobuy.platform.common.enums.GrassUserTypeEnum;
5 -import com.yohobuy.platform.common.enums.GrassVirtualUserGroupEnum;  
6 import com.yohobuy.platform.dal.grass.*; 9 import com.yohobuy.platform.dal.grass.*;
7 -import com.yohobuy.platform.dal.grass.model.GrassArticle;  
8 -import com.yohobuy.platform.dal.grass.model.GrassArticlePraise;  
9 -import com.yohobuy.platform.dal.grass.model.GrassUserAchieve;  
10 -import com.yohobuy.platform.dal.grass.model.GrassUserAttention; 10 +import com.yohobuy.platform.dal.grass.model.*;
11 import com.yohobuy.platform.grass.service.IGrassVirtualService; 11 import com.yohobuy.platform.grass.service.IGrassVirtualService;
12 import org.apache.commons.collections.CollectionUtils; 12 import org.apache.commons.collections.CollectionUtils;
13 import org.apache.commons.lang.StringUtils; 13 import org.apache.commons.lang.StringUtils;
14 import org.slf4j.Logger; 14 import org.slf4j.Logger;
15 import org.slf4j.LoggerFactory; 15 import org.slf4j.LoggerFactory;
16 import org.springframework.beans.factory.annotation.Autowired; 16 import org.springframework.beans.factory.annotation.Autowired;
  17 +import org.springframework.beans.factory.annotation.Value;
17 import org.springframework.stereotype.Service; 18 import org.springframework.stereotype.Service;
18 import java.util.*; 19 import java.util.*;
19 -import java.util.function.Function;  
20 import java.util.stream.Collectors; 20 import java.util.stream.Collectors;
21 import static com.yoho.tools.common.utils.RandomUtil.getRandom; 21 import static com.yoho.tools.common.utils.RandomUtil.getRandom;
22 22
@@ -46,13 +46,17 @@ public class GrassUserVirtualImpl implements IGrassVirtualService{ @@ -46,13 +46,17 @@ public class GrassUserVirtualImpl implements IGrassVirtualService{
46 46
47 public static final long INTERVAL = 60 * 60 * 1000l;//1小时 47 public static final long INTERVAL = 60 * 60 * 1000l;//1小时
48 48
49 -// public static final long INTERVAL = 1 * 60 * 60 * 1000l;//1小时 49 + @Value("${api.yoho.url:http://api.yoho.cn}")
  50 + private String apiUrl;
50 51
  52 + @Autowired
  53 + private ServiceCaller serviceCaller;
51 54
52 /** 55 /**
53 * 种草文章--增加点赞数 56 * 种草文章--增加点赞数
54 - * 1)审核通过、被推荐,推荐时间 在72小时以内的文章 57 + * 1)审核通过、被推荐,推荐时间 在72小时以内的文章(时间可配)
55 * 2)随机点赞 58 * 2)随机点赞
  59 + * 3)第一次点赞的,发送站内信,取消点赞,此次再点赞的,不发站内信(二期修改)
56 */ 60 */
57 @Override 61 @Override
58 public void addVirtualPraise() { 62 public void addVirtualPraise() {
@@ -68,40 +72,102 @@ public class GrassUserVirtualImpl implements IGrassVirtualService{ @@ -68,40 +72,102 @@ public class GrassUserVirtualImpl implements IGrassVirtualService{
68 return ; 72 return ;
69 } 73 }
70 74
  75 + Map<Integer,GrassArticle > articleInfoMap = articleList.stream().collect(Collectors.toMap(GrassArticle::getId, obj -> obj));
71 List<Integer> articleIds = articleList.stream().map(GrassArticle::getId).distinct().collect(Collectors.toList()); 76 List<Integer> articleIds = articleList.stream().map(GrassArticle::getId).distinct().collect(Collectors.toList());
72 logger.info("addVirtualPraise, update articleList size={}, articleIds={} ", articleList.size(), articleIds); 77 logger.info("addVirtualPraise, update articleList size={}, articleIds={} ", articleList.size(), articleIds);
73 //点赞阈值 78 //点赞阈值
74 String threshold = configReader.getString("platform.grass.virtualpraise.threshold",""); 79 String threshold = configReader.getString("platform.grass.virtualpraise.threshold","");
75 String s[] = StringUtils.split(threshold,","); 80 String s[] = StringUtils.split(threshold,",");
76 - int min = Integer.valueOf(s[0]);  
77 - int max = Integer.valueOf(s[1]);  
78 - //虚拟马甲用户  
79 - List<Integer> allVirtualUids = grassVirtualUserDao.selectVirtualsByGroup(GrassVirtualUserGroupEnum.COMMON.getValue()); 81 + //可用马甲(普通马甲 社区大号 外部刷评论马甲)
  82 + List<Integer> groupList = Arrays.asList(new Integer[]{1,4,6});
  83 + List<Integer> allVirtualUids = grassVirtualUserDao.selectVirtualsByGroupList(groupList);
80 if(CollectionUtils.isEmpty(allVirtualUids)){ 84 if(CollectionUtils.isEmpty(allVirtualUids)){
81 logger.warn("addVirtualPraise no virtual user "); 85 logger.warn("addVirtualPraise no virtual user ");
82 return; 86 return;
83 } 87 }
84 - //这些文章已有的点赞明细 88 + //1)这些文章已有的点赞明细(剔除掉已经点赞的马甲,曾经点赞取消的马甲 也需要特殊处理)
85 List<GrassArticlePraise> praiseList = grassArticlePraiseDao.selectByArticles(articleIds); 89 List<GrassArticlePraise> praiseList = grassArticlePraiseDao.selectByArticles(articleIds);
86 Map<Integer,List<Integer>> articlePraiseMap = new HashMap<>(); 90 Map<Integer,List<Integer>> articlePraiseMap = new HashMap<>();
  91 + Map<Integer,List<Integer>> canceledPraiseMap = new HashMap<>();
87 for(GrassArticlePraise praise : praiseList){ 92 for(GrassArticlePraise praise : praiseList){
88 Integer articleId = praise.getArticleId(); 93 Integer articleId = praise.getArticleId();
89 - if(articlePraiseMap.get(articleId) == null){  
90 - articlePraiseMap.put(articleId, new ArrayList<>()); 94 + Integer status = praise.getStatus();
  95 + Integer uid = praise.getUid();
  96 + if(status == 0 ){//正常的点赞
  97 + if(articlePraiseMap.get(articleId) == null){
  98 + articlePraiseMap.put(articleId, new ArrayList<>());
  99 + }
  100 + articlePraiseMap.get(articleId).add(uid);
  101 + }
  102 + if(status == 1){//点赞被取消了
  103 + if(canceledPraiseMap.get(articleId) == null){
  104 + canceledPraiseMap.put(articleId,new ArrayList<>());
  105 + }
  106 + canceledPraiseMap.get(articleId).add(uid);
91 } 107 }
92 - articlePraiseMap.get(articleId).add(praise.getUid());  
93 } 108 }
94 109
95 - Map<Integer,GrassUserAchieve> commonMap = new HashMap<>();  
96 - Map<Integer,GrassUserAchieve> guangMap = new HashMap<>();  
97 - List<GrassArticlePraise> newPraiseList = new ArrayList<>(); 110 + //2)点赞逻辑,要区分逛的作者 和 普通作者
  111 + Map<Integer,GrassUserAchieve> commonUserAchieveMap = new HashMap<>();
  112 + Map<Integer,GrassUserAchieve> guangUserAchieveMap = new HashMap<>();
  113 + //新增的点赞明细
  114 + List<GrassArticlePraise> newPariseDetail = new ArrayList<>();
  115 + //被取消的点赞,只需要update状态就可以了,并且不需要发站内信
  116 + List<GrassArticlePraise> updateDetailList = new ArrayList<>();
  117 +
  118 + //普通用户发布的文章
  119 + List<GrassArticle> commonArtcileList = articleList.stream().filter(obj -> obj.getAuthorType() == null || obj.getAuthorType() == GrassUserTypeEnum.COMMON.getValue() )
  120 + .collect(Collectors.toList());
  121 + //逛作者发布的文章
  122 + List<GrassArticle> guangArtcileList = articleList.stream().filter(obj -> obj.getAuthorType() != null && obj.getAuthorType() == GrassUserTypeEnum.GUANG.getValue() )
  123 + .collect(Collectors.toList());
  124 +
  125 + //1)普通文章点赞处理
  126 + doVirtualPraise(commonArtcileList,articlePraiseMap,canceledPraiseMap,allVirtualUids,s,currentTime,commonUserAchieveMap,1,newPariseDetail,updateDetailList);
  127 + //2)逛文章点赞处理
  128 + doVirtualPraise(guangArtcileList,articlePraiseMap,canceledPraiseMap,allVirtualUids,s,currentTime,guangUserAchieveMap,2,newPariseDetail,updateDetailList);
  129 +
  130 + if(CollectionUtils.isEmpty(newPariseDetail) && CollectionUtils.isEmpty(updateDetailList)){
  131 + logger.info("addOrUpdateVirtualPraise list is empty");
  132 + return;
  133 + }
  134 + List<GrassUserAchieve> userAchieveList = new ArrayList<>();
  135 + userAchieveList.addAll(commonUserAchieveMap.values());
  136 + userAchieveList.addAll(guangUserAchieveMap.values());
  137 + logger.info("start to addVirtualPraise,praiseDetailList={}",newPariseDetail);
  138 + logger.info("start to updateVirtualPraise,updateDetailList={}",updateDetailList);
  139 + logger.info("start to addVirtualPraise,articleList={}",articleList);
  140 + logger.info("start to addOrUpdateUserAchieve,userAchieveList={}",userAchieveList);
98 141
99 - //点赞 142 + //1)新增点赞明细表
  143 + if(CollectionUtils.isNotEmpty(newPariseDetail)){
  144 + grassArticlePraiseDao.batchInsert(newPariseDetail);
  145 + }
  146 +
  147 + //2)更新点赞文章表(更改状态)
  148 + if(CollectionUtils.isNotEmpty(updateDetailList)){
  149 + grassArticlePraiseDao.batchUpdatePraiseStatus(updateDetailList);
  150 + }
  151 + //3)更新文章表(批量更新文章表)
  152 + grassArticleDao.batchUpdatePraiseCount(articleList);
  153 + logger.info("addVirtualPraise update grassArticle success!");
  154 + //4)批量更新作者表(新增或者update)
  155 + userAchieveDAO.batchUpdatePraise(userAchieveList);
  156 + //5)发送站内信(通知作者 文章获赞)---后期增加
  157 + sendAddPariseMessage(newPariseDetail,articleInfoMap);
  158 + logger.info("addVirtualPraise success!");
  159 + }
  160 +
  161 + //点赞逻辑
  162 + private void doVirtualPraise(List<GrassArticle> articleList, Map<Integer,List<Integer>> articlePraiseMap, Map<Integer,List<Integer>> canceledPraiseMap,
  163 + List<Integer> allVirtualUids, String[] s,long currentTime,
  164 + Map<Integer,GrassUserAchieve> userMap,Integer authorType,
  165 + List<GrassArticlePraise> newPariseDetail, List<GrassArticlePraise> updateDetailList) {
  166 + int min = Integer.valueOf(s[0]);
  167 + int max = Integer.valueOf(s[1]);
100 for(GrassArticle article : articleList){ 168 for(GrassArticle article : articleList){
101 Integer articleId = article.getId(); 169 Integer articleId = article.getId();
102 int authorUid = article.getAuthorUid(); 170 int authorUid = article.getAuthorUid();
103 - int authorType = article.getAuthorType() == null ? 1 : article.getAuthorType() ;  
104 -  
105 //选择虚拟马甲 171 //选择虚拟马甲
106 List<Integer> oldPraiseList = articlePraiseMap.get(articleId); 172 List<Integer> oldPraiseList = articlePraiseMap.get(articleId);
107 List<Integer> tempList = new ArrayList<>(); 173 List<Integer> tempList = new ArrayList<>();
@@ -124,10 +190,16 @@ public class GrassUserVirtualImpl implements IGrassVirtualService{ @@ -124,10 +190,16 @@ public class GrassUserVirtualImpl implements IGrassVirtualService{
124 praiseDetail.setCreateTime((int) (currentTime/1000l)); 190 praiseDetail.setCreateTime((int) (currentTime/1000l));
125 praiseDetail.setUpdateTime((int) (currentTime/1000l)); 191 praiseDetail.setUpdateTime((int) (currentTime/1000l));
126 praiseDetail.setStatus(0);//0 --点赞 1 ---取消 192 praiseDetail.setStatus(0);//0 --点赞 1 ---取消
127 - newPraiseList.add(praiseDetail); 193 + //已经存在点赞,但是被取消的情况
  194 + List<Integer> canceledList = canceledPraiseMap.get(articleId);
  195 + if(CollectionUtils.isNotEmpty(canceledList) && canceledList.contains(virtualUid)){//当前马甲以前点赞过
  196 + updateDetailList.add(praiseDetail);
  197 + }else{
  198 + //新增的点赞明细
  199 + newPariseDetail.add(praiseDetail);
  200 + }
128 } 201 }
129 202
130 -  
131 //2)更新文章获赞总数 203 //2)更新文章获赞总数
132 article.setPraiseCount(random);//增加点赞数 204 article.setPraiseCount(random);//增加点赞数
133 article.setUpdateTime(currentTime); 205 article.setUpdateTime(currentTime);
@@ -135,52 +207,106 @@ public class GrassUserVirtualImpl implements IGrassVirtualService{ @@ -135,52 +207,106 @@ public class GrassUserVirtualImpl implements IGrassVirtualService{
135 //3)更新作者 获赞总数 207 //3)更新作者 获赞总数
136 //同一个作者 必须要累加计数 否则更新结果不正确 208 //同一个作者 必须要累加计数 否则更新结果不正确
137 GrassUserAchieve userAchieve = new GrassUserAchieve(); 209 GrassUserAchieve userAchieve = new GrassUserAchieve();
138 - if(authorType == GrassUserTypeEnum.COMMON.getValue() && commonMap.get(authorUid)!=null){  
139 - //求和  
140 - userAchieve = commonMap.get(authorUid);  
141 - userAchieve.setPraiseAmount(userAchieve.getPraiseAmount() + random);  
142 - continue;  
143 - }  
144 - if(authorType == GrassUserTypeEnum.GUANG.getValue() && guangMap.get(authorUid)!=null){ 210 + if(userMap.get(authorUid)!=null){
145 //求和 211 //求和
146 - userAchieve = guangMap.get(authorUid); 212 + userAchieve = userMap.get(authorUid);
147 userAchieve.setPraiseAmount(userAchieve.getPraiseAmount() + random); 213 userAchieve.setPraiseAmount(userAchieve.getPraiseAmount() + random);
148 continue; 214 continue;
149 } 215 }
  216 +
150 userAchieve.setUid(authorUid); 217 userAchieve.setUid(authorUid);
151 userAchieve.setUserType(authorType); 218 userAchieve.setUserType(authorType);
152 userAchieve.setUpdateTime((int) (currentTime / 1000l)); 219 userAchieve.setUpdateTime((int) (currentTime / 1000l));
153 //新增加的点赞数 220 //新增加的点赞数
154 userAchieve.setPraiseAmount(random); 221 userAchieve.setPraiseAmount(random);
155 - if(authorType == GrassUserTypeEnum.COMMON.getValue()){  
156 - commonMap.put(authorUid, userAchieve); 222 + userMap.put(authorUid, userAchieve);
  223 + }
  224 + }
  225 +
  226 + private void sendAddPariseMessage(List<GrassArticlePraise> pariseDetail,Map<Integer,GrassArticle> articleInfoMap) {
  227 + if(CollectionUtils.isEmpty(pariseDetail)){
  228 + return;
  229 + }
  230 + //批量插入的时候没有获取到id(依赖版本较低,获取不到),重查一遍
  231 + List<GrassArticlePraise> newPariseDetail = grassArticlePraiseDao.selectByArticleAndUids(pariseDetail);
  232 + List<GrassInBoxAddReq> reqList = new ArrayList<>();
  233 + //发送站内信(第一次点赞的时候发送)
  234 + for(GrassArticlePraise newPraise : newPariseDetail){
  235 + Integer id = newPraise.getId();
  236 + Integer artcileId = newPraise.getArticleId();
  237 + Integer uid = newPraise.getUid();
  238 + GrassArticle grassArticle = articleInfoMap.get(artcileId);
  239 + //如果不是有货的作者,也不发送站内信
  240 + if(id == null || artcileId == null || uid == null || grassArticle == null){
  241 + continue;
157 } 242 }
158 - if(authorType == GrassUserTypeEnum.GUANG.getValue()){  
159 - guangMap.put(authorUid, userAchieve); 243 + Integer authorUid = grassArticle.getAuthorUid();
  244 + Integer authorType = grassArticle.getAuthorType();
  245 + if(authorType == GrassUserTypeEnum.GUANG.getValue()){//非有货用户,不发送站内信
  246 + continue;
160 } 247 }
  248 + //发送站内信
  249 + GrassInBoxAddReq req = new GrassInBoxAddReq();
  250 + req.setUid(authorUid);
  251 + req.setAttachValue(String.valueOf(id));
  252 + req.setBusinessType(GrassInboxBusinessTypeEnum.SYSTEM_PRAISE_ARTICLE.getBusinessType());
  253 + req.setOptUid(uid);
  254 + req.setParams("");
  255 + reqList.add(req);
161 } 256 }
162 257
163 - List<GrassUserAchieve> userPraiseList = new ArrayList<>();  
164 - userPraiseList.addAll(commonMap.values());  
165 - userPraiseList.addAll(guangMap.values());  
166 - logger.info("start to addVirtualPraise,newPraiseList={}",newPraiseList);  
167 - logger.info("start to addVirtualPraise,articleList={}",articleList);  
168 - logger.info("start to addVirtualPraise,userPraiseList={}",userPraiseList);  
169 - //更新点赞明细表  
170 - grassArticlePraiseDao.batchInsertOrUpdate(newPraiseList);  
171 - //更新文章表(批量更新文章表)  
172 - grassArticleDao.batchUpdatePraiseCount(articleList);  
173 - logger.info("addVirtualPraise update grassArticle success!");  
174 - //批量更新作者表(新增或者update)  
175 - userAchieveDAO.batchUpdatePraise(userPraiseList);  
176 - logger.info("addVirtualPraise success!"); 258 + sendMessage(reqList);
177 } 259 }
178 260
  261 + private void sendMessage(List<GrassInBoxAddReq> reqList) {
  262 + //(调sns接口,批量发送站内信)
  263 + try{
  264 + String url = apiUrl + "?method=app.grass.addBatchInBoxNew";
  265 + logger.info("before addBatchInBoxNew, url is: {}, req is {}", url, reqList);
  266 + serviceCaller.post("app.clearGrassCache", url, reqList, String.class, null);
  267 + }catch (Exception e){
  268 + logger.info("failed refreshGrassCache, req is {}, error is {}", reqList , e);
  269 + }
  270 + }
  271 +
  272 +
  273 + private void sendAddFansMessage(List<GrassUserAttention> attentions) {
  274 + if(CollectionUtils.isEmpty(attentions)){
  275 + logger.info("sendAddFansMessage list is empty");
  276 + return;
  277 + }
  278 + List<GrassUserAttention> newAttentions = grassUserAttentionDao.selectByAuthorAndUids(attentions);
  279 + List<GrassInBoxAddReq> reqList = new ArrayList<>();
  280 + //发送站内信(第一次成为粉丝的时候才发送)
  281 + for(GrassUserAttention attention : newAttentions){
  282 + Integer id = attention.getId();
  283 + Integer authorUid = attention.getFollowUid();//作者uid
  284 + Integer fanUid = attention.getUid();
  285 + if(id == null || authorUid == null || fanUid == null ){
  286 + continue;
  287 + }
  288 + if(attention.getAuthorType() == GrassUserTypeEnum.GUANG.getValue()){//逛作者不需要发站内信
  289 + continue;
  290 + }
  291 + //发送站内信
  292 + GrassInBoxAddReq req = new GrassInBoxAddReq();
  293 + req.setUid(authorUid);
  294 + req.setAttachValue(String.valueOf(id));
  295 + req.setBusinessType(GrassInboxBusinessTypeEnum.SYSTEM_ATTENTION_USER.getBusinessType());
  296 + req.setOptUid(fanUid);
  297 + req.setParams("");
  298 + reqList.add(req);
  299 + }
  300 + sendMessage(reqList);
  301 + }
  302 +
  303 +
179 304
180 /** 305 /**
181 * 种草作者--增加粉丝 306 * 种草作者--增加粉丝
182 - * 1)审核通过、被推荐,推荐时间 在72小时以内的文章 的作者 307 + * 1)审核通过、被推荐,推荐时间 在72小时以内的文章 的作者(时间可配)
183 * 2)随机增粉 308 * 2)随机增粉
  309 + * 3)首次成为作者粉丝,发送站内信(不push消息),取消,此次再次关注的,不发站内信
184 */ 310 */
185 311
186 @Override 312 @Override
@@ -206,8 +332,9 @@ public class GrassUserVirtualImpl implements IGrassVirtualService{ @@ -206,8 +332,9 @@ public class GrassUserVirtualImpl implements IGrassVirtualService{
206 int min = Integer.valueOf(s[0]); 332 int min = Integer.valueOf(s[0]);
207 int max = Integer.valueOf(s[1]); 333 int max = Integer.valueOf(s[1]);
208 334
209 - //所有的马甲用户 status =1属于普通组的马甲  
210 - List<Integer> allVirtualUids = grassVirtualUserDao.selectVirtualsByGroup(GrassVirtualUserGroupEnum.COMMON.getValue()); 335 + //马甲用户(普通马甲 社区大号 外部刷评论马甲),并且状态开启
  336 + List<Integer> groupList = Arrays.asList(new Integer[]{1,4,6});
  337 + List<Integer> allVirtualUids = grassVirtualUserDao.selectVirtualsByGroupList(groupList);
211 if(CollectionUtils.isEmpty(allVirtualUids)){ 338 if(CollectionUtils.isEmpty(allVirtualUids)){
212 logger.warn("addVirtualFans no virtual user "); 339 logger.warn("addVirtualFans no virtual user ");
213 return; 340 return;
@@ -218,11 +345,9 @@ public class GrassUserVirtualImpl implements IGrassVirtualService{ @@ -218,11 +345,9 @@ public class GrassUserVirtualImpl implements IGrassVirtualService{
218 Set<Integer> commonUid = articleList.stream(). 345 Set<Integer> commonUid = articleList.stream().
219 filter(obj -> obj.getAuthorType() == GrassUserTypeEnum.COMMON.getValue()).map(GrassArticle::getAuthorUid) 346 filter(obj -> obj.getAuthorType() == GrassUserTypeEnum.COMMON.getValue()).map(GrassArticle::getAuthorUid)
220 .collect(Collectors.toSet()); 347 .collect(Collectors.toSet());
221 -  
222 Set<Integer> guangUid = articleList.stream(). 348 Set<Integer> guangUid = articleList.stream().
223 filter(obj -> obj.getAuthorType() == GrassUserTypeEnum.GUANG.getValue()).map(GrassArticle::getAuthorUid) 349 filter(obj -> obj.getAuthorType() == GrassUserTypeEnum.GUANG.getValue()).map(GrassArticle::getAuthorUid)
224 .collect(Collectors.toSet()); 350 .collect(Collectors.toSet());
225 -  
226 List<Integer> allUids = new ArrayList<>(); 351 List<Integer> allUids = new ArrayList<>();
227 allUids.addAll(commonUid); 352 allUids.addAll(commonUid);
228 allUids.addAll(guangUid); 353 allUids.addAll(guangUid);
@@ -230,7 +355,9 @@ public class GrassUserVirtualImpl implements IGrassVirtualService{ @@ -230,7 +355,9 @@ public class GrassUserVirtualImpl implements IGrassVirtualService{
230 //这些作者已有的粉丝信息 355 //这些作者已有的粉丝信息
231 List<GrassUserAttention> fansList = grassUserAttentionDao.selectFansByUids(allUids); 356 List<GrassUserAttention> fansList = grassUserAttentionDao.selectFansByUids(allUids);
232 Map<Integer,List<Integer>> commonUserFansMap = new HashMap<>(); 357 Map<Integer,List<Integer>> commonUserFansMap = new HashMap<>();
  358 + Map<Integer,List<Integer>> commonUserCanceledFansMap = new HashMap<>();
233 Map<Integer,List<Integer>> guangUserFansMap = new HashMap<>(); 359 Map<Integer,List<Integer>> guangUserFansMap = new HashMap<>();
  360 + Map<Integer,List<Integer>> guangUserCanceledFansMap = new HashMap<>();
234 361
235 //(普通作者的粉丝 && 逛小编的粉丝)--已有的粉丝 362 //(普通作者的粉丝 && 逛小编的粉丝)--已有的粉丝
236 //粉丝本身一定是有货用户,不需要区分类型 363 //粉丝本身一定是有货用户,不需要区分类型
@@ -238,24 +365,40 @@ public class GrassUserVirtualImpl implements IGrassVirtualService{ @@ -238,24 +365,40 @@ public class GrassUserVirtualImpl implements IGrassVirtualService{
238 int authorUid = temp.getFollowUid();//作者 365 int authorUid = temp.getFollowUid();//作者
239 int fanUid = temp.getUid();//粉丝 366 int fanUid = temp.getUid();//粉丝
240 int authorType = temp.getAuthorType() == null ? 1 : temp.getAuthorType(); 367 int authorType = temp.getAuthorType() == null ? 1 : temp.getAuthorType();
241 - if(authorType == GrassUserTypeEnum.COMMON.getValue()){ 368 + //1)普通作者, 已被关注--剔除这些uid
  369 + if(authorType == GrassUserTypeEnum.COMMON.getValue() && temp.getStatus() == 0){
242 if(commonUserFansMap.get(authorUid) == null){ 370 if(commonUserFansMap.get(authorUid) == null){
243 commonUserFansMap.put(authorUid, new ArrayList<>()); 371 commonUserFansMap.put(authorUid, new ArrayList<>());
244 } 372 }
245 commonUserFansMap.get(authorUid).add(fanUid); 373 commonUserFansMap.get(authorUid).add(fanUid);
246 continue; 374 continue;
247 } 375 }
248 -  
249 - if(authorType == GrassUserTypeEnum.GUANG.getValue()){ 376 + //2)普通作者, 取消关注--后续特殊处理
  377 + if(authorType == GrassUserTypeEnum.COMMON.getValue() && temp.getStatus() == 1){
  378 + if(commonUserCanceledFansMap.get(authorUid) == null){
  379 + commonUserCanceledFansMap.put(authorUid, new ArrayList<>());
  380 + }
  381 + commonUserCanceledFansMap.get(authorUid).add(fanUid);
  382 + continue;
  383 + }
  384 + //3)逛作者, 已被关注--剔除这些uid
  385 + if(authorType == GrassUserTypeEnum.GUANG.getValue() && temp.getStatus() == 0){
250 if(guangUserFansMap.get(authorUid) == null){ 386 if(guangUserFansMap.get(authorUid) == null){
251 guangUserFansMap.put(authorUid, new ArrayList<>()); 387 guangUserFansMap.put(authorUid, new ArrayList<>());
252 } 388 }
253 guangUserFansMap.get(authorUid).add(fanUid); 389 guangUserFansMap.get(authorUid).add(fanUid);
254 } 390 }
255 - 391 + //3)逛作者, 取消关注--后续特殊处理
  392 + if(authorType == GrassUserTypeEnum.GUANG.getValue() && temp.getStatus() == 1){
  393 + if(guangUserCanceledFansMap.get(authorUid) == null){
  394 + guangUserCanceledFansMap.put(authorUid, new ArrayList<>());
  395 + }
  396 + guangUserCanceledFansMap.get(authorUid).add(fanUid);
  397 + }
256 } 398 }
257 399
258 - List<GrassUserAttention> userAttentions = new ArrayList<>(); 400 + List<GrassUserAttention> newUserAttentions = new ArrayList<>();
  401 + List<GrassUserAttention> updateUserAttentions = new ArrayList<>();
259 List<GrassUserAchieve> userAchieveFansList = new ArrayList<>(); 402 List<GrassUserAchieve> userAchieveFansList = new ArrayList<>();
260 //普通作者--增粉数据 403 //普通作者--增粉数据
261 for(Integer authorUid : commonUid){ 404 for(Integer authorUid : commonUid){
@@ -267,8 +410,11 @@ public class GrassUserVirtualImpl implements IGrassVirtualService{ @@ -267,8 +410,11 @@ public class GrassUserVirtualImpl implements IGrassVirtualService{
267 tempList.removeAll(oldFansList); 410 tempList.removeAll(oldFansList);
268 } 411 }
269 Set<Integer> randomUidList = getRandomFans(tempList, min, max); 412 Set<Integer> randomUidList = getRandomFans(tempList, min, max);
  413 + List<Integer> canceledList = commonUserCanceledFansMap.get(authorUid);
270 //随机增粉 414 //随机增粉
271 - addFans(randomUidList,authorUid,GrassUserTypeEnum.COMMON.getValue(),userAttentions, userAchieveFansList,currentTime); 415 + addFans(randomUidList,authorUid,GrassUserTypeEnum.COMMON.getValue(),
  416 + newUserAttentions, updateUserAttentions,
  417 + userAchieveFansList,currentTime,canceledList);
272 } 418 }
273 419
274 //逛作者--增粉数据 420 //逛作者--增粉数据
@@ -281,18 +427,23 @@ public class GrassUserVirtualImpl implements IGrassVirtualService{ @@ -281,18 +427,23 @@ public class GrassUserVirtualImpl implements IGrassVirtualService{
281 tempList.removeAll(oldFansList); 427 tempList.removeAll(oldFansList);
282 } 428 }
283 Set<Integer> randomUidList = getRandomFans(tempList, min, max); 429 Set<Integer> randomUidList = getRandomFans(tempList, min, max);
  430 + List<Integer> canceledList = guangUserCanceledFansMap.get(authorUid);
284 //随机增粉 431 //随机增粉
285 - addFans(randomUidList,authorUid,GrassUserTypeEnum.GUANG.getValue(),userAttentions, userAchieveFansList,currentTime); 432 + addFans(randomUidList,authorUid,GrassUserTypeEnum.GUANG.getValue(),
  433 + newUserAttentions,updateUserAttentions, userAchieveFansList,currentTime,canceledList);
286 } 434 }
287 435
288 //更新数据库 436 //更新数据库
289 //批量新增粉丝明细表 437 //批量新增粉丝明细表
290 - if(CollectionUtils.isEmpty(userAttentions)){ 438 + if(CollectionUtils.isEmpty(newUserAttentions) && CollectionUtils.isEmpty(updateUserAttentions)){
291 logger.info("addVirtualFans success, no update! userAttentions is empty "); 439 logger.info("addVirtualFans success, no update! userAttentions is empty ");
292 return ; 440 return ;
293 } 441 }
294 442
295 //马甲的关注数 443 //马甲的关注数
  444 + List<GrassUserAttention> userAttentions = new ArrayList<>();
  445 + userAttentions.addAll(newUserAttentions);
  446 + userAttentions.addAll(updateUserAttentions);
296 Map<Integer, Long> attMap = userAttentions.stream() 447 Map<Integer, Long> attMap = userAttentions.stream()
297 .collect(Collectors.groupingBy(GrassUserAttention::getUid,Collectors.counting())); 448 .collect(Collectors.groupingBy(GrassUserAttention::getUid,Collectors.counting()));
298 449
@@ -308,24 +459,38 @@ public class GrassUserVirtualImpl implements IGrassVirtualService{ @@ -308,24 +459,38 @@ public class GrassUserVirtualImpl implements IGrassVirtualService{
308 userAchieveAttList.add(user); 459 userAchieveAttList.add(user);
309 } 460 }
310 461
311 -  
312 - logger.info("addVirtualFans update grassUserAttention,userAttentions={}", userAttentions); 462 + logger.info("addVirtualFans insert grassUserAttention,newUserAttentions={}", newUserAttentions);
  463 + logger.info("addVirtualFans update grassUserAttention,updateUserAttentions={}", updateUserAttentions);
313 logger.info("addVirtualFans update userAchieve userAchieveFansList={}",userAchieveFansList); 464 logger.info("addVirtualFans update userAchieve userAchieveFansList={}",userAchieveFansList);
314 logger.info("addVirtualFans update userAchieve userAchieveAttList={}",userAchieveAttList); 465 logger.info("addVirtualFans update userAchieve userAchieveAttList={}",userAchieveAttList);
315 - //1)更新关注明细表  
316 - grassUserAttentionDao.batchInsert(userAttentions);  
317 - logger.info("addVirtualFans update grassUserAttention success!");  
318 - //2)批量更新作者表,增加作者对应的粉丝数 466 + //1)新增关注明细表
  467 + if(CollectionUtils.isNotEmpty(newUserAttentions)){
  468 + grassUserAttentionDao.batchInsert(newUserAttentions);
  469 + logger.info("addVirtualFans batchInsert grassUserAttention success!");
  470 + }
  471 +
  472 + //2)批量更新关注明细(之前取消了,现在再关注)
  473 + if(CollectionUtils.isNotEmpty(updateUserAttentions)){
  474 + grassUserAttentionDao.batchUpdate(updateUserAttentions);
  475 + logger.info("addVirtualFans batchUpdate grassUserAttention success!");
  476 + }
  477 +
  478 + //3)批量更新作者表,增加作者对应的粉丝数
319 userAchieveDAO.batchUpdateFans(userAchieveFansList); 479 userAchieveDAO.batchUpdateFans(userAchieveFansList);
320 logger.info("addVirtualFans batchUpdateFans success!"); 480 logger.info("addVirtualFans batchUpdateFans success!");
321 - //3)批量更新作者表,增加粉丝对应的关注数 481 + //4)批量更新作者表,增加粉丝对应的关注数
322 userAchieveDAO.batchInsertOrUpAttentions(userAchieveAttList); 482 userAchieveDAO.batchInsertOrUpAttentions(userAchieveAttList);
  483 + //5)发送站内信
  484 + sendAddFansMessage(newUserAttentions);
323 logger.info("addVirtualFans success!"); 485 logger.info("addVirtualFans success!");
324 -  
325 } 486 }
326 487
  488 +
  489 +
327 //增粉数据 490 //增粉数据
328 - private void addFans(Set<Integer> randomUidList, Integer authorUid, int authorType, List<GrassUserAttention> userAttentions, List<GrassUserAchieve> userAchieveList,Long currentTime) { 491 + private void addFans(Set<Integer> randomUidList, Integer authorUid, int authorType,
  492 + List<GrassUserAttention> newUserAttentions,List<GrassUserAttention> updateUserAttentions,
  493 + List<GrassUserAchieve> userAchieveList,Long currentTime,List<Integer> canceledList) {
329 if(CollectionUtils.isEmpty(randomUidList)){ 494 if(CollectionUtils.isEmpty(randomUidList)){
330 logger.info("addVirtualFans randomUidList is empty, authorUid={}, ",authorUid); 495 logger.info("addVirtualFans randomUidList is empty, authorUid={}, ",authorUid);
331 return ; 496 return ;
@@ -333,7 +498,6 @@ public class GrassUserVirtualImpl implements IGrassVirtualService{ @@ -333,7 +498,6 @@ public class GrassUserVirtualImpl implements IGrassVirtualService{
333 498
334 //粉丝明细表 499 //粉丝明细表
335 for(Integer randomUid : randomUidList){ 500 for(Integer randomUid : randomUidList){
336 - //粉丝明细表  
337 GrassUserAttention attention = new GrassUserAttention(); 501 GrassUserAttention attention = new GrassUserAttention();
338 attention.setFollowUid(authorUid); 502 attention.setFollowUid(authorUid);
339 attention.setAuthorType(authorType); 503 attention.setAuthorType(authorType);
@@ -342,9 +506,13 @@ public class GrassUserVirtualImpl implements IGrassVirtualService{ @@ -342,9 +506,13 @@ public class GrassUserVirtualImpl implements IGrassVirtualService{
342 attention.setUpdateTime((int) (currentTime / 1000l)); 506 attention.setUpdateTime((int) (currentTime / 1000l));
343 attention.setAttentionType(1);//1-关注用户 507 attention.setAttentionType(1);//1-关注用户
344 attention.setStatus(0);//0 --正常 1删除 508 attention.setStatus(0);//0 --正常 1删除
345 - userAttentions.add(attention); 509 + //粉丝明细表
  510 + if(CollectionUtils.isNotEmpty(canceledList) && canceledList.contains(randomUid)){
  511 + updateUserAttentions.add(attention);
  512 + }else{
  513 + newUserAttentions.add(attention);
  514 + }
346 } 515 }
347 -  
348 //作者的粉丝需要增加 516 //作者的粉丝需要增加
349 //粉丝总数表(一条数据) 517 //粉丝总数表(一条数据)
350 GrassUserAchieve userAchieve = new GrassUserAchieve(); 518 GrassUserAchieve userAchieve = new GrassUserAchieve();