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

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 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 * @return
*/ */
Integer deleteLinkedPortfolioData(@Param("id") Integer id); 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.entity.Follow;
import com.rymcu.vertical.web.api.exception.BaseApiException; import com.rymcu.vertical.web.api.exception.BaseApiException;
import java.util.List;
/** /**
* @author ronger * @author ronger
*/ */
@ -32,4 +34,12 @@ public interface FollowService extends Service<Follow> {
* @throws BaseApiException * @throws BaseApiException
*/ */
Boolean cancelFollow(Follow 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.insertSelective(newArticle);
articleMapper.insertArticleContent(newArticle.getIdArticle(), articleContent, articleContentHtml); articleMapper.insertArticleContent(newArticle.getIdArticle(), articleContent, articleContentHtml);
} else { } else {
isUpdate = true;
newArticle = articleMapper.selectByPrimaryKey(article.getIdArticle()); newArticle = articleMapper.selectByPrimaryKey(article.getIdArticle());
// 如果文章之前状态为草稿则应视为新发布文章
if (defaultStatus.equals(newArticle.getArticleStatus())) {
isUpdate = true;
} else {
isUpdate = false;
}
if (!user.getIdUser().equals(newArticle.getArticleAuthorId())) { if (!user.getIdUser().equals(newArticle.getArticleAuthorId())) {
map.put("message", "非法访问!"); map.put("message", "非法访问!");
return map; return map;
@ -153,8 +158,22 @@ public class ArticleServiceImpl extends AbstractService<Article> implements Arti
articleMapper.updateArticleContent(newArticle.getIdArticle(), articleContent, articleContentHtml); articleMapper.updateArticleContent(newArticle.getIdArticle(), articleContent, articleContentHtml);
} }
if (notification && defaultStatus.equals(newArticle.getArticleStatus())) { // 发送相关通知
if (defaultStatus.equals(newArticle.getArticleStatus())) {
// 发送系统通知
if (notification) {
NotificationUtils.sendAnnouncement(newArticle.getIdArticle(), NotificationConstant.Article, newArticle.getArticleTitle()); 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); tagService.saveTagArticle(newArticle);
@ -175,7 +194,7 @@ public class ArticleServiceImpl extends AbstractService<Article> implements Arti
String articlePreviewContent = articleContentHtml.substring(0, length); String articlePreviewContent = articleContentHtml.substring(0, length);
newArticle.setArticlePreviewContent(Html2TextUtil.getContent(articlePreviewContent)); newArticle.setArticlePreviewContent(Html2TextUtil.getContent(articlePreviewContent));
} }
articleMapper.updateByPrimaryKeySelective(newArticle); articleMapper.updateArticleLinkAndPreviewContent(newArticle.getIdArticle(), newArticle.getArticleLink(), newArticle.getArticlePermalink(), newArticle.getArticlePreviewContent());
// 推送百度 SEO // 推送百度 SEO
if (!ProjectConstant.ENV.equals(env) 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 org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.List;
/** /**
* @author ronger * @author ronger
@ -47,4 +48,12 @@ public class FollowServiceImpl extends AbstractService<Follow> implements Follow
int result = followMapper.delete(follow); int result = followMapper.delete(follow);
return result == 0; 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()); user = userService.findById(comment.getCommentAuthorId().toString());
notificationDTO.setAuthor(genAuthor(user)); notificationDTO.setAuthor(genAuthor(user));
break; 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: default:
break; break;
} }

View File

@ -1,7 +1,10 @@
package com.rymcu.vertical.util; 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.Notification;
import com.rymcu.vertical.entity.User; import com.rymcu.vertical.entity.User;
import com.rymcu.vertical.service.FollowService;
import com.rymcu.vertical.service.NotificationService; import com.rymcu.vertical.service.NotificationService;
import com.rymcu.vertical.service.UserService; import com.rymcu.vertical.service.UserService;
@ -11,6 +14,7 @@ import java.util.concurrent.*;
/** /**
* 消息通知工具类 * 消息通知工具类
*
* @author ronger * @author ronger
*/ */
public class NotificationUtils { public class NotificationUtils {
@ -19,36 +23,32 @@ public class NotificationUtils {
private static NotificationService notificationService = SpringContextHolder.getBean(NotificationService.class); private static NotificationService notificationService = SpringContextHolder.getBean(NotificationService.class);
@Resource @Resource
private static UserService userService = SpringContextHolder.getBean(UserService.class); 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) { public static void sendAnnouncement(Integer dataId, String dataType, String dataSummary) {
ExecutorService executor= new ThreadPoolExecutor(1,1,0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); ExecutorService executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
CompletableFuture.supplyAsync(()-> { CompletableFuture.supplyAsync(() -> {
System.out.println("------------------- 开始执行消息通知 ------------------");
try { try {
List<User> users = userService.findAll(); List<User> users = userService.findAll();
users.forEach(user -> { users.forEach(user -> {
Notification notification = notificationService.findNotification(user.getIdUser(),dataId,dataType); saveNotification(user.getIdUser(), dataId, dataType, dataSummary);
if (notification == null) {
Integer result = notificationService.save(user.getIdUser(),dataId,dataType,dataSummary);
if (result == 0) {
saveNotification(user.getIdUser(),dataId,dataType,dataSummary);
}
}
}); });
} catch (Exception ex) { } catch (Exception ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
return 0; return 0;
},executor); }, executor);
} }
public static void saveNotification(Integer idUser, Integer dataId, String dataType, String dataSummary) { public static void saveNotification(Integer idUser, Integer dataId, String dataType, String dataSummary) {
ExecutorService executor= new ThreadPoolExecutor(1,1,0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); ExecutorService executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
CompletableFuture.supplyAsync(()-> { CompletableFuture.supplyAsync(() -> {
try { try {
Notification notification = notificationService.findNotification(idUser,dataId,dataType); Notification notification = notificationService.findNotification(idUser, dataId, dataType);
if (notification == null) { if (notification == null || NotificationConstant.UpdateArticle.equals(dataType)) {
Integer result = notificationService.save(idUser,dataId,dataType,dataSummary); System.out.println("------------------- 开始执行消息通知 ------------------");
Integer result = notificationService.save(idUser, dataId, dataType, dataSummary);
if (result == 0) { if (result == 0) {
// TODO 记录操作失败数据 // TODO 记录操作失败数据
} }
@ -58,7 +58,29 @@ public class NotificationUtils {
ex.printStackTrace(); ex.printStackTrace();
} }
return 0; 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 id="updateArticleTags">
update vertical_article set article_tags = #{tags} where id = #{idArticle} update vertical_article set article_tags = #{tags} where id = #{idArticle}
</update> </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 id="deleteTagArticle">
delete from vertical_tag_article where id_article = #{id} delete from vertical_tag_article where id_article = #{id}
</delete> </delete>