关注通知功能(用户,文章)

This commit is contained in:
x ronger 2020-09-26 00:11:55 +08:00
parent 35b9106f88
commit bff07a5973
8 changed files with 108 additions and 21 deletions

View File

@ -12,4 +12,8 @@ public class NotificationConstant {
public static String Comment = "2";
public static String PostArticle = "3";
public static String UpdateArticle = "4";
}

View File

@ -158,4 +158,14 @@ public interface ArticleMapper extends Mapper<Article> {
* @return
*/
Integer deleteLinkedPortfolioData(@Param("id") Integer id);
/**
* 更新文章连接及预览内容
* @param idArticle
* @param articleLink
* @param articlePermalink
* @param articlePreviewContent
* @return
*/
Integer updateArticleLinkAndPreviewContent(@Param("idArticle") Integer idArticle, @Param("articleLink") String articleLink, @Param("articlePermalink") String articlePermalink, @Param("articlePreviewContent") String articlePreviewContent);
}

View File

@ -4,6 +4,8 @@ import com.rymcu.vertical.core.service.Service;
import com.rymcu.vertical.entity.Follow;
import com.rymcu.vertical.web.api.exception.BaseApiException;
import java.util.List;
/**
* @author ronger
*/
@ -32,4 +34,12 @@ public interface FollowService extends Service<Follow> {
* @throws BaseApiException
*/
Boolean cancelFollow(Follow follow) throws BaseApiException;
/**
* 获取关注用户者数据
* @param followType
* @param followingId
* @return
*/
List<Follow> findByFollowingId(String followType, Integer followingId);
}

View File

@ -140,8 +140,13 @@ public class ArticleServiceImpl extends AbstractService<Article> implements Arti
articleMapper.insertSelective(newArticle);
articleMapper.insertArticleContent(newArticle.getIdArticle(), articleContent, articleContentHtml);
} else {
isUpdate = true;
newArticle = articleMapper.selectByPrimaryKey(article.getIdArticle());
// 如果文章之前状态为草稿则应视为新发布文章
if (defaultStatus.equals(newArticle.getArticleStatus())) {
isUpdate = true;
} else {
isUpdate = false;
}
if (!user.getIdUser().equals(newArticle.getArticleAuthorId())) {
map.put("message", "非法访问!");
return map;
@ -153,8 +158,22 @@ public class ArticleServiceImpl extends AbstractService<Article> implements Arti
articleMapper.updateArticleContent(newArticle.getIdArticle(), articleContent, articleContentHtml);
}
if (notification && defaultStatus.equals(newArticle.getArticleStatus())) {
NotificationUtils.sendAnnouncement(newArticle.getIdArticle(), NotificationConstant.Article, newArticle.getArticleTitle());
// 发送相关通知
if (defaultStatus.equals(newArticle.getArticleStatus())) {
// 发送系统通知
if (notification) {
NotificationUtils.sendAnnouncement(newArticle.getIdArticle(), NotificationConstant.Article, newArticle.getArticleTitle());
} else {
// 发送关注通知
StringBuffer dataSummary = new StringBuffer();
if (isUpdate) {
dataSummary.append(user.getNickname()).append("更新了文章: ").append(newArticle.getArticleTitle());
NotificationUtils.sendArticlePush(newArticle.getIdArticle(), NotificationConstant.UpdateArticle, dataSummary.toString(), newArticle.getArticleAuthorId());
} else {
dataSummary.append(user.getNickname()).append("发布了文章: ").append(newArticle.getArticleTitle());
NotificationUtils.sendArticlePush(newArticle.getIdArticle(), NotificationConstant.PostArticle, dataSummary.toString(), newArticle.getArticleAuthorId());
}
}
}
tagService.saveTagArticle(newArticle);
@ -175,7 +194,7 @@ public class ArticleServiceImpl extends AbstractService<Article> implements Arti
String articlePreviewContent = articleContentHtml.substring(0, length);
newArticle.setArticlePreviewContent(Html2TextUtil.getContent(articlePreviewContent));
}
articleMapper.updateByPrimaryKeySelective(newArticle);
articleMapper.updateArticleLinkAndPreviewContent(newArticle.getIdArticle(), newArticle.getArticleLink(), newArticle.getArticlePermalink(), newArticle.getArticlePreviewContent());
// 推送百度 SEO
if (!ProjectConstant.ENV.equals(env)

View File

@ -12,6 +12,7 @@ import com.rymcu.vertical.web.api.exception.BaseApiException;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
* @author ronger
@ -47,4 +48,12 @@ public class FollowServiceImpl extends AbstractService<Follow> implements Follow
int result = followMapper.delete(follow);
return result == 0;
}
@Override
public List<Follow> findByFollowingId(String followType, Integer followingId) {
Follow follow = new Follow();
follow.setFollowingType(followType);
follow.setFollowingId(followingId);
return followMapper.select(follow);
}
}

View File

@ -89,6 +89,16 @@ public class NotificationServiceImpl extends AbstractService<Notification> imple
user = userService.findById(comment.getCommentAuthorId().toString());
notificationDTO.setAuthor(genAuthor(user));
break;
case "3":
// 关注用户发布文章
case "4":
// 关注文章更新
article = articleService.findArticleDTOById(notification.getDataId(), 0);
notificationDTO.setDataTitle("关注通知");
notificationDTO.setDataUrl(article.getArticlePermalink());
user = userService.findById(article.getArticleAuthorId().toString());
notificationDTO.setAuthor(genAuthor(user));
break;
default:
break;
}

View File

@ -1,7 +1,10 @@
package com.rymcu.vertical.util;
import com.rymcu.vertical.core.constant.NotificationConstant;
import com.rymcu.vertical.entity.Follow;
import com.rymcu.vertical.entity.Notification;
import com.rymcu.vertical.entity.User;
import com.rymcu.vertical.service.FollowService;
import com.rymcu.vertical.service.NotificationService;
import com.rymcu.vertical.service.UserService;
@ -11,6 +14,7 @@ import java.util.concurrent.*;
/**
* 消息通知工具类
*
* @author ronger
*/
public class NotificationUtils {
@ -19,36 +23,32 @@ public class NotificationUtils {
private static NotificationService notificationService = SpringContextHolder.getBean(NotificationService.class);
@Resource
private static UserService userService = SpringContextHolder.getBean(UserService.class);
@Resource
private static FollowService followService = SpringContextHolder.getBean(FollowService.class);
public static void sendAnnouncement(Integer dataId, String dataType, String dataSummary) {
ExecutorService executor= new ThreadPoolExecutor(1,1,0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
CompletableFuture.supplyAsync(()-> {
System.out.println("------------------- 开始执行消息通知 ------------------");
ExecutorService executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
CompletableFuture.supplyAsync(() -> {
try {
List<User> users = userService.findAll();
users.forEach(user -> {
Notification notification = notificationService.findNotification(user.getIdUser(),dataId,dataType);
if (notification == null) {
Integer result = notificationService.save(user.getIdUser(),dataId,dataType,dataSummary);
if (result == 0) {
saveNotification(user.getIdUser(),dataId,dataType,dataSummary);
}
}
saveNotification(user.getIdUser(), dataId, dataType, dataSummary);
});
} catch (Exception ex) {
ex.printStackTrace();
}
return 0;
},executor);
}, executor);
}
public static void saveNotification(Integer idUser, Integer dataId, String dataType, String dataSummary) {
ExecutorService executor= new ThreadPoolExecutor(1,1,0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
CompletableFuture.supplyAsync(()-> {
ExecutorService executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
CompletableFuture.supplyAsync(() -> {
try {
Notification notification = notificationService.findNotification(idUser,dataId,dataType);
if (notification == null) {
Integer result = notificationService.save(idUser,dataId,dataType,dataSummary);
Notification notification = notificationService.findNotification(idUser, dataId, dataType);
if (notification == null || NotificationConstant.UpdateArticle.equals(dataType)) {
System.out.println("------------------- 开始执行消息通知 ------------------");
Integer result = notificationService.save(idUser, dataId, dataType, dataSummary);
if (result == 0) {
// TODO 记录操作失败数据
}
@ -58,7 +58,29 @@ public class NotificationUtils {
ex.printStackTrace();
}
return 0;
},executor);
}, executor);
}
public static void sendArticlePush(Integer dataId, String dataType, String dataSummary, Integer articleAuthorId) {
ExecutorService executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
CompletableFuture.supplyAsync(() -> {
try {
List<Follow> follows;
if (NotificationConstant.PostArticle.equals(dataType)) {
// 关注用户通知
follows = followService.findByFollowingId("0", articleAuthorId);
} else {
// 关注文章通知
follows = followService.findByFollowingId("3", articleAuthorId);
}
follows.forEach(follow -> {
saveNotification(follow.getFollowerId(), dataId, dataType, dataSummary);
});
} catch (Exception ex) {
ex.printStackTrace();
}
return 0;
}, executor);
}
}

View File

@ -74,6 +74,9 @@
<update id="updateArticleTags">
update vertical_article set article_tags = #{tags} where id = #{idArticle}
</update>
<update id="updateArticleLinkAndPreviewContent">
update vertical_article set article_link = #{articleLink}, article_permalink = #{articlePermalink}, article_preview_content = #{articlePreviewContent} where id = #{idArticle}
</update>
<delete id="deleteTagArticle">
delete from vertical_tag_article where id_article = #{id}
</delete>