✨ 关注通知功能(用户,文章)
This commit is contained in:
parent
35b9106f88
commit
bff07a5973
@ -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";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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())) {
|
// 发送相关通知
|
||||||
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);
|
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)
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user