通知功能完善

This commit is contained in:
x ronger 2020-01-27 12:12:10 +08:00
parent 911c694433
commit f8d777e562
11 changed files with 226 additions and 10 deletions

View File

@ -0,0 +1,13 @@
package com.rymcu.vertical.core.constant;
/**
* 消息通知类型
* @author ronger
*/
public class NotificationConstant {
public static String Article = "0";
public static String Follow = "1";
}

View File

@ -1,5 +1,6 @@
package com.rymcu.vertical.entity; package com.rymcu.vertical.entity;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data; import lombok.Data;
import javax.persistence.Column; import javax.persistence.Column;
@ -52,5 +53,6 @@ public class Notification implements Serializable,Cloneable {
* 是否已读 * 是否已读
*/ */
@Column(name = "created_time") @Column(name = "created_time")
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date createdTime; private Date createdTime;
} }

View File

@ -18,5 +18,36 @@ public interface NotificationMapper extends Mapper<Notification> {
*/ */
List<Notification> selectUnreadNotifications(@Param("idUser") Integer idUser); List<Notification> selectUnreadNotifications(@Param("idUser") Integer idUser);
/**
* 获取消息数据
* @param idUser
* @return
*/
List<Notification> selectNotifications(@Param("idUser") Integer idUser); List<Notification> selectNotifications(@Param("idUser") Integer idUser);
/**
* 获取消息数据
* @param idUser
* @param dataId
* @param dataType
* @return
*/
Notification selectNotification(@Param("idUser") Integer idUser, @Param("dataId") Integer dataId, @Param("dataType") String dataType);
/**
* 创建消息通知
* @param idUser
* @param dataId
* @param dataType
* @param dataSummary
* @return
*/
Integer insertNotification(@Param("idUser") Integer idUser, @Param("dataId") Integer dataId, @Param("dataType") String dataType, @Param("dataSummary") String dataSummary);
/**
* 标记消息已读
* @param id
* @return
*/
Integer readNotification(@Param("id") Integer id);
} }

View File

@ -2,10 +2,12 @@ package com.rymcu.vertical.service;
import com.rymcu.vertical.core.service.Service; import com.rymcu.vertical.core.service.Service;
import com.rymcu.vertical.entity.Notification; import com.rymcu.vertical.entity.Notification;
import org.apache.ibatis.annotations.Param;
import java.util.List; import java.util.List;
/** /**
* 消息通知接口类
* @author ronger * @author ronger
*/ */
public interface NotificationService extends Service<Notification> { public interface NotificationService extends Service<Notification> {
@ -22,4 +24,29 @@ public interface NotificationService extends Service<Notification> {
* @return * @return
*/ */
List<Notification> findNotifications(Integer idUser); List<Notification> findNotifications(Integer idUser);
/**
* 获取消息数据
* @param idUser
* @param dataId
* @param dataType
* @return
*/
Notification findNotification(Integer idUser, Integer dataId, String dataType);
/**
* 创建系统通知
* @param idUser
* @param dataId
* @param dataType
* @param dataSummary
* @return
*/
Integer save(Integer idUser, Integer dataId, String dataType, String dataSummary);
/**
* 标记消息已读
* @param id
*/
void readNotification(Integer id);
} }

View File

@ -93,4 +93,11 @@ public interface UserService extends Service<User> {
* @return * @return
*/ */
Map checkNickname(Integer idUser, String nickname); Map checkNickname(Integer idUser, String nickname);
/**
* 获取用户权限
* @param idUser
* @return
*/
Integer findRoleWeightsByUser(Integer idUser);
} }

View File

@ -1,5 +1,6 @@
package com.rymcu.vertical.service.impl; package com.rymcu.vertical.service.impl;
import com.rymcu.vertical.core.constant.NotificationConstant;
import com.rymcu.vertical.core.service.AbstractService; import com.rymcu.vertical.core.service.AbstractService;
import com.rymcu.vertical.dto.ArticleDTO; import com.rymcu.vertical.dto.ArticleDTO;
import com.rymcu.vertical.dto.ArticleTagDTO; import com.rymcu.vertical.dto.ArticleTagDTO;
@ -11,12 +12,11 @@ import com.rymcu.vertical.mapper.ArticleMapper;
import com.rymcu.vertical.service.ArticleService; import com.rymcu.vertical.service.ArticleService;
import com.rymcu.vertical.service.TagService; import com.rymcu.vertical.service.TagService;
import com.rymcu.vertical.service.UserService; import com.rymcu.vertical.service.UserService;
import com.rymcu.vertical.util.BaiDuUtils; import com.rymcu.vertical.util.*;
import com.rymcu.vertical.util.Html2TextUtil;
import com.rymcu.vertical.util.UserUtils;
import com.rymcu.vertical.util.Utils;
import com.rymcu.vertical.web.api.exception.BaseApiException; import com.rymcu.vertical.web.api.exception.BaseApiException;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.commons.text.StringEscapeUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -40,6 +40,8 @@ public class ArticleServiceImpl extends AbstractService<Article> implements Arti
private TagService tagService; private TagService tagService;
@Resource @Resource
private UserService userService; private UserService userService;
@Value("${reserved-words}")
private String reservedWords;
private static final String DOMAIN = "https://rymcu.com"; private static final String DOMAIN = "https://rymcu.com";
@ -99,6 +101,17 @@ public class ArticleServiceImpl extends AbstractService<Article> implements Arti
String articleContent = article.getArticleContent(); String articleContent = article.getArticleContent();
String articleContentHtml = article.getArticleContentHtml(); String articleContentHtml = article.getArticleContentHtml();
User user = UserUtils.getWxCurrentUser(); User user = UserUtils.getWxCurrentUser();
boolean checkTags = checkTags(articleTags);
boolean notification = false;
if (checkTags) {
Integer roleWeights = userService.findRoleWeightsByUser(user.getIdUser());
if (roleWeights > 2) {
map.put("message", StringEscapeUtils.unescapeJava(reservedWords) + "标签为系统保留标签!");
return map;
} else {
notification = true;
}
}
Article article1; Article article1;
if(article.getIdArticle() == null || article.getIdArticle() == 0){ if(article.getIdArticle() == null || article.getIdArticle() == 0){
article1 = new Article(); article1 = new Article();
@ -131,6 +144,11 @@ public class ArticleServiceImpl extends AbstractService<Article> implements Arti
article1.setUpdatedTime(new Date()); article1.setUpdatedTime(new Date());
articleMapper.updateArticleContent(article1.getIdArticle(),articleContent,articleContentHtml); articleMapper.updateArticleContent(article1.getIdArticle(),articleContent,articleContentHtml);
} }
if (notification) {
NotificationUtils.sendAnnouncement(article1.getIdArticle(), NotificationConstant.Article, article1.getArticleTitle());
}
tagService.saveTagArticle(article1); tagService.saveTagArticle(article1);
articleMapper.updateByPrimaryKeySelective(article1); articleMapper.updateByPrimaryKeySelective(article1);
@ -138,6 +156,29 @@ public class ArticleServiceImpl extends AbstractService<Article> implements Arti
return map; return map;
} }
private boolean checkTags(String articleTags) {
if (StringUtils.isNotBlank(reservedWords) && StringUtils.isNotBlank(articleTags)) {
String[] words = StringEscapeUtils.unescapeJava(reservedWords).split(",");
String[] tags = articleTags.split(",");
for(String word: words) {
if (StringUtils.isBlank(word)) {
continue;
}
for (String tag: tags) {
if (StringUtils.isBlank(tag)) {
continue;
}
if (tag.equals(word)) {
return true;
}
}
}
} else {
return false;
}
return false;
}
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public Map delete(Integer id) { public Map delete(Integer id) {

View File

@ -29,4 +29,19 @@ public class NotificationServiceImpl extends AbstractService<Notification> imple
List<Notification> list = notificationMapper.selectNotifications(idUser); List<Notification> list = notificationMapper.selectNotifications(idUser);
return list; return list;
} }
@Override
public Notification findNotification(Integer idUser, Integer dataId, String dataType) {
return notificationMapper.selectNotification(idUser,dataId,dataType);
}
@Override
public Integer save(Integer idUser, Integer dataId, String dataType, String dataSummary) {
return notificationMapper.insertNotification(idUser,dataId,dataType,dataSummary);
}
@Override
public void readNotification(Integer id) {
notificationMapper.readNotification(id);
}
} }

View File

@ -202,4 +202,9 @@ public class UserServiceImpl extends AbstractService<User> implements UserServic
} }
return map; return map;
} }
@Override
public Integer findRoleWeightsByUser(Integer idUser) {
return userMapper.selectRoleWeightsByUser(idUser);
}
} }

View File

@ -0,0 +1,64 @@
package com.rymcu.vertical.util;
import com.rymcu.vertical.entity.Notification;
import com.rymcu.vertical.entity.User;
import com.rymcu.vertical.service.NotificationService;
import com.rymcu.vertical.service.UserService;
import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.*;
/**
* 消息通知工具类
* @author ronger
*/
public class NotificationUtils {
@Resource
private static NotificationService notificationService = SpringContextHolder.getBean(NotificationService.class);
@Resource
private static UserService userService = SpringContextHolder.getBean(UserService.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("------------------- 开始执行消息通知 ------------------");
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);
}
}
});
} catch (Exception ex) {
ex.printStackTrace();
}
return 0;
},executor);
}
private 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(()-> {
try {
Notification notification = notificationService.findNotification(idUser,dataId,dataType);
if (notification == null) {
Integer result = notificationService.save(idUser,dataId,dataType,dataSummary);
if (result == 0) {
// TODO 记录操作失败数据
}
}
} catch (Exception ex) {
// TODO 记录操作失败数据
ex.printStackTrace();
}
return 0;
},executor);
}
}

View File

@ -10,10 +10,7 @@ import com.rymcu.vertical.service.NotificationService;
import com.rymcu.vertical.util.UserUtils; import com.rymcu.vertical.util.UserUtils;
import com.rymcu.vertical.util.Utils; import com.rymcu.vertical.util.Utils;
import com.rymcu.vertical.web.api.exception.BaseApiException; import com.rymcu.vertical.web.api.exception.BaseApiException;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.List; import java.util.List;
@ -50,4 +47,9 @@ public class NotificationController {
return GlobalResultGenerator.genSuccessResult(map); return GlobalResultGenerator.genSuccessResult(map);
} }
@PutMapping("/read/{id}")
public void read(@PathVariable Integer id) {
notificationService.readNotification(id);
}
} }

View File

@ -10,10 +10,19 @@
<result column="has_read" property="hasRead"></result> <result column="has_read" property="hasRead"></result>
<result column="created_time" property="createdTime"></result> <result column="created_time" property="createdTime"></result>
</resultMap> </resultMap>
<insert id="insertNotification">
insert into vertical_notification (id_user, data_type, data_id, data_summary, created_time) values (#{idUser}, #{dataType}, #{dataId}, #{dataSummary}, sysdate())
</insert>
<update id="readNotification">
update vertical_notification set has_read = '1' where id = #{id}
</update>
<select id="selectUnreadNotifications" resultMap="BaseResultMapper"> <select id="selectUnreadNotifications" resultMap="BaseResultMapper">
select * from vertical_notification where has_read = '0' and id_user = #{idUser} select * from vertical_notification where has_read = '0' and id_user = #{idUser} order by created_time desc
</select> </select>
<select id="selectNotifications" resultMap="BaseResultMapper"> <select id="selectNotifications" resultMap="BaseResultMapper">
select * from vertical_notification where id_user = #{idUser} select * from vertical_notification where id_user = #{idUser} order by created_time desc
</select>
<select id="selectNotification" resultMap="BaseResultMapper">
select * from vertical_notification where id_user = #{idUser} and data_id = #{dataId} and data_type = #{dataType}
</select> </select>
</mapper> </mapper>